~repos /tide-jsx

#rust#proc-macro#jsx

git clone https://pyrossh.dev/repos/tide-jsx.git

Tide + JSX


a6199b76 Gal Schlezinger

6 years ago
escape strings
Cargo.lock CHANGED
@@ -22,6 +22,11 @@ name = "difference"
22
22
  version = "2.0.0"
23
23
  source = "registry+https://github.com/rust-lang/crates.io-index"
24
24
 
25
+ [[package]]
26
+ name = "htmlescape"
27
+ version = "0.3.1"
28
+ source = "registry+https://github.com/rust-lang/crates.io-index"
29
+
25
30
  [[package]]
26
31
  name = "output_vt100"
27
32
  version = "0.1.2"
@@ -61,6 +66,7 @@ dependencies = [
61
66
  name = "render"
62
67
  version = "0.1.0"
63
68
  dependencies = [
69
+ "htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
64
70
  "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
65
71
  "render_macros 0.1.0",
66
72
  ]
@@ -120,6 +126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
120
126
  "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
121
127
  "checksum ctor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3e061727ebef83bbccac7c27b9a5ff9fd83094d34cb20f4005440a9562a27de7"
122
128
  "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
129
+ "checksum htmlescape 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163"
123
130
  "checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
124
131
  "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
125
132
  "checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8"
render/Cargo.toml CHANGED
@@ -14,6 +14,7 @@ license = "MIT"
14
14
 
15
15
  [dependencies]
16
16
  render_macros = { path = "../render_macros", version = "0.1" }
17
+ htmlescape = "0.3"
17
18
 
18
19
  [dev-dependencies]
19
20
  pretty_assertions = "0.6"
render/src/lib.rs CHANGED
@@ -1,18 +1,18 @@
1
1
  //! > 🔏 A safe and simple template engine with the ergonomics of JSX
2
- //!
2
+ //!
3
3
  //! The `Renderable` trait contains a simple function that returns `String`. This is very handy for type-safe HTML templates, but can also work for writing tree-like terminal coloring mechanism like ReasonML's [Pastel](https://reason-native.com/docs/pastel/).
4
- //!
4
+ //!
5
5
  //! ## Why this is different from `typed-html`?
6
- //!
6
+ //!
7
7
  //! `typed-html` is a wonderful library. Unfortunately, it focused its power in strictness of the HTML spec itself, and doesn't allow arbitrary compositions of custom elements.
8
- //!
8
+ //!
9
9
  //! `render` takes a different approach. For now, HTML is not typed at all. It can get any key and get any string value. The main focus is custom components, so you can create a composable and declarative template with no runtime errors.
10
- //!
10
+ //!
11
11
  //! ## Usage
12
- //!
12
+ //!
13
13
  //! ```rust
14
14
  //! #![feature(proc_macro_hygiene)]
15
- //!
15
+ //!
16
16
  //! // A simple HTML 5 doctype declaration
17
17
  //! use render::html::HTML5Doctype;
18
18
  //! use render::{
@@ -23,14 +23,14 @@
23
23
  //! // A trait for custom components
24
24
  //! Renderable,
25
25
  //! };
26
- //!
26
+ //!
27
27
  //! // This can be any layout we want
28
28
  //! #[derive(Debug)]
29
29
  //! struct Page<'a, T: Renderable> {
30
30
  //! title: &'a str,
31
31
  //! children: T,
32
32
  //! }
33
- //!
33
+ //!
34
34
  //! // Implementing `Renderable` gives the ability to compose
35
35
  //! // components
36
36
  //! impl<'a, T: Renderable> Renderable for Page<'a, T> {
@@ -48,7 +48,7 @@
48
48
  //! }
49
49
  //! }
50
50
  //! }
51
- //!
51
+ //!
52
52
  //! // This can be a route in Rocket, the web framework,
53
53
  //! // for instance.
54
54
  //! pub fn some_page(user_name: &str) -> String {
@@ -83,3 +83,4 @@ pub use fragment::Fragment;
83
83
  pub use render_macros::{html, rsx};
84
84
  pub use renderable::Renderable;
85
85
  pub use simple_element::SimpleElement;
86
+ pub use text_element::Raw;
render/src/text_element.rs CHANGED
@@ -1,17 +1,58 @@
1
1
  use crate::Renderable;
2
+ use htmlescape::encode_minimal;
2
3
 
3
- /// Renders the string
4
+ /// Renders an escaped-html string
4
- /// > TODO: this should escape HTML!
5
5
  impl Renderable for String {
6
6
  fn render(self) -> String {
7
- self
7
+ encode_minimal(&self)
8
8
  }
9
9
  }
10
10
 
11
- /// Renders the string
11
+ /// Renders an escaped-html string
12
- /// > TODO: this should escape HTML!
13
12
  impl Renderable for &str {
14
13
  fn render(self) -> String {
15
- self.to_string()
14
+ encode_minimal(self)
16
15
  }
17
16
  }
17
+
18
+ /// A raw (unencoded) html string
19
+ #[derive(Debug)]
20
+ pub struct Raw<'s>(&'s str);
21
+
22
+ impl<'s> From<&'s str> for Raw<'s> {
23
+ fn from(s: &'s str) -> Self {
24
+ Raw(s)
25
+ }
26
+ }
27
+
28
+ /// A raw (unencoded) html string
29
+ impl<'s> Renderable for Raw<'s> {
30
+ fn render(self) -> String {
31
+ self.0.to_string()
32
+ }
33
+ }
34
+
35
+ #[cfg(test)]
36
+ mod tests {
37
+ use super::*;
38
+
39
+ #[test]
40
+ fn decodes_html() {
41
+ let rendered = "<Hello />".render();
42
+ assert_eq!(rendered, "&lt;Hello /&gt;");
43
+ }
44
+
45
+ #[test]
46
+ fn allows_raw_text() {
47
+ let rendered = Raw::from("<Hello />").render();
48
+ assert_eq!(rendered, "<Hello />");
49
+ }
50
+ }
51
+
52
+ /// Creates a raw (unencoded) html string
53
+ #[macro_export]
54
+ macro_rules! raw {
55
+ ($text:expr) => {
56
+ ::render::Raw::from($text)
57
+ };
58
+ }
render_tests/src/lib.rs CHANGED
@@ -44,3 +44,15 @@ pub fn it_works() -> String {
44
44
  pub fn verify_works() {
45
45
  println!("{}", it_works());
46
46
  }
47
+
48
+ #[test]
49
+ pub fn works_with_raw() {
50
+ use pretty_assertions::assert_eq;
51
+ use render::raw;
52
+
53
+ let actual = html! {
54
+ <div>{raw!("<Hello />")}</div>
55
+ };
56
+
57
+ assert_eq!(actual, "<div><Hello /></div>");
58
+ }