~repos /tide-jsx

#rust#proc-macro#jsx

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

Tide + JSX


377f3108 Gal Schlezinger

6 years ago
README
Files changed (2) hide show
  1. README.md +61 -0
  2. render_tests/src/lib.rs +65 -0
README.md ADDED
@@ -0,0 +1,61 @@
1
+ # Render
2
+
3
+ > A simple template engine with the type-safety of Rust and the ergonomics of JSX
4
+
5
+ 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/).
6
+
7
+ ## Why this is different from `typed-html`?
8
+
9
+ `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.
10
+
11
+ `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.
12
+
13
+ ## Usage
14
+
15
+ ```rust
16
+ // A simple HTML 5 doctype declaration
17
+ use render::html::HTML5Doctype;
18
+ use render::{
19
+ // A macro to compose components in JSX fashion
20
+ html,
21
+ // A component that just render its children
22
+ Fragment,
23
+ // A trait for custom components
24
+ Renderable,
25
+ };
26
+
27
+ // This can be any layout we want
28
+ #[derive(Debug)]
29
+ struct Page<'a, T: Renderable> {
30
+ title: &'a str,
31
+ children: T,
32
+ }
33
+
34
+ // Implementing `Renderable` gives the ability to compose
35
+ // components
36
+ impl<'a, T: Renderable> Renderable for Page<'a, T> {
37
+ fn render(self) -> String {
38
+ html! {
39
+ <Fragment>
40
+ <HTML5Doctype />
41
+ <html>
42
+ <head><title>{self.title}</title></head>
43
+ <body>
44
+ {self.children}
45
+ </body>
46
+ </html>
47
+ </Fragment>
48
+ }
49
+ }
50
+ }
51
+
52
+ // This can be a route in Rocket, the web framework,
53
+ // for instance.
54
+ pub fn some_page(user_name: &str) -> String {
55
+ html! {
56
+ <Page title={"Home"}>
57
+ {format!("Welcome, {}", user_name)}
58
+ </Page>
59
+ }
60
+ }
61
+ ```
render_tests/src/lib.rs CHANGED
@@ -44,3 +44,68 @@ pub fn it_works() -> String {
44
44
  pub fn verify_works() {
45
45
  println!("{}", it_works());
46
46
  }
47
+
48
+ pub mod readme_code {
49
+ // A simple HTML 5 doctype declaration
50
+ use render::html::HTML5Doctype;
51
+ use render::{
52
+ // A macro to compose components in JSX fashion
53
+ html,
54
+ // A component that just render its children
55
+ Fragment,
56
+ // A trait for custom components
57
+ Renderable,
58
+ };
59
+
60
+ // This can be any layout we want
61
+ #[derive(Debug)]
62
+ struct Page<'a, T: Renderable> {
63
+ title: &'a str,
64
+ children: T,
65
+ }
66
+
67
+ // Implementing `Renderable` gives the ability to compose
68
+ // components
69
+ impl<'a, T: Renderable> Renderable for Page<'a, T> {
70
+ fn render(self) -> String {
71
+ html! {
72
+ <Fragment>
73
+ <HTML5Doctype />
74
+ <html>
75
+ <head><title>{self.title}</title></head>
76
+ <body>
77
+ {self.children}
78
+ </body>
79
+ </html>
80
+ </Fragment>
81
+ }
82
+ }
83
+ }
84
+
85
+ // This can be a route in Rocket, the web framework,
86
+ // for instance.
87
+ pub fn some_page(user_name: &str) -> String {
88
+ html! {
89
+ <Page title={"Home"}>
90
+ {format!("Welcome, {}", user_name)}
91
+ </Page>
92
+ }
93
+ }
94
+ }
95
+
96
+ #[test]
97
+ fn test_readme_stuff() {
98
+ use pretty_assertions::assert_eq;
99
+ let result = readme_code::some_page("Gal");
100
+ let expected = concat!(
101
+ "<!DOCTYPE html>",
102
+ "<html>",
103
+ "<head><title>Home</title></head>",
104
+ "<body>",
105
+ "Welcome, Gal",
106
+ "</body>",
107
+ "</html>"
108
+ );
109
+
110
+ assert_eq!(result, expected);
111
+ }