~repos /tide-jsx

#rust#proc-macro#jsx

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

Tide + JSX


553f893e Naitik Shah

5 years ago
Prepare for running in stable Rust (#27)
.github/workflows/rust.yml CHANGED
@@ -12,7 +12,7 @@ jobs:
12
12
  steps:
13
13
  - uses: hecrj/setup-rust-action@v1
14
14
  with:
15
- rust-version: nightly
15
+ rust-version: beta
16
16
  - uses: actions/checkout@v1
17
17
  - name: Build
18
18
  run: cargo build --verbose
Cargo.lock CHANGED
@@ -22,6 +22,21 @@ 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 = "glob"
27
+ version = "0.3.0"
28
+ source = "registry+https://github.com/rust-lang/crates.io-index"
29
+
30
+ [[package]]
31
+ name = "itoa"
32
+ version = "0.4.5"
33
+ source = "registry+https://github.com/rust-lang/crates.io-index"
34
+
35
+ [[package]]
36
+ name = "lazy_static"
37
+ version = "1.4.0"
38
+ source = "registry+https://github.com/rust-lang/crates.io-index"
39
+
25
40
  [[package]]
26
41
  name = "output_vt100"
27
42
  version = "0.1.2"
@@ -41,6 +56,30 @@ dependencies = [
41
56
  "output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
42
57
  ]
43
58
 
59
+ [[package]]
60
+ name = "proc-macro-error"
61
+ version = "1.0.2"
62
+ source = "registry+https://github.com/rust-lang/crates.io-index"
63
+ dependencies = [
64
+ "proc-macro-error-attr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
65
+ "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
66
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
67
+ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
68
+ "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
69
+ ]
70
+
71
+ [[package]]
72
+ name = "proc-macro-error-attr"
73
+ version = "1.0.2"
74
+ source = "registry+https://github.com/rust-lang/crates.io-index"
75
+ dependencies = [
76
+ "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
77
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
78
+ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
79
+ "syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
80
+ "version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
81
+ ]
82
+
44
83
  [[package]]
45
84
  name = "proc-macro2"
46
85
  version = "1.0.3"
@@ -70,6 +109,7 @@ name = "render_macros"
70
109
  version = "0.3.1"
71
110
  dependencies = [
72
111
  "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
112
+ "proc-macro-error 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
73
113
  "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
74
114
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
75
115
  "render 0.3.1",
@@ -82,6 +122,40 @@ version = "0.3.1"
82
122
  dependencies = [
83
123
  "pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
84
124
  "render 0.3.1",
125
+ "trybuild 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
126
+ ]
127
+
128
+ [[package]]
129
+ name = "ryu"
130
+ version = "1.0.5"
131
+ source = "registry+https://github.com/rust-lang/crates.io-index"
132
+
133
+ [[package]]
134
+ name = "serde"
135
+ version = "1.0.111"
136
+ source = "registry+https://github.com/rust-lang/crates.io-index"
137
+ dependencies = [
138
+ "serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
139
+ ]
140
+
141
+ [[package]]
142
+ name = "serde_derive"
143
+ version = "1.0.111"
144
+ source = "registry+https://github.com/rust-lang/crates.io-index"
145
+ dependencies = [
146
+ "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
147
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
148
+ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
149
+ ]
150
+
151
+ [[package]]
152
+ name = "serde_json"
153
+ version = "1.0.55"
154
+ source = "registry+https://github.com/rust-lang/crates.io-index"
155
+ dependencies = [
156
+ "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
157
+ "ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
158
+ "serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
85
159
  ]
86
160
 
87
161
  [[package]]
@@ -94,11 +168,55 @@ dependencies = [
94
168
  "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
95
169
  ]
96
170
 
171
+ [[package]]
172
+ name = "syn-mid"
173
+ version = "0.5.0"
174
+ source = "registry+https://github.com/rust-lang/crates.io-index"
175
+ dependencies = [
176
+ "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
177
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
178
+ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
179
+ ]
180
+
181
+ [[package]]
182
+ name = "termcolor"
183
+ version = "1.1.0"
184
+ source = "registry+https://github.com/rust-lang/crates.io-index"
185
+ dependencies = [
186
+ "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
187
+ ]
188
+
189
+ [[package]]
190
+ name = "toml"
191
+ version = "0.5.6"
192
+ source = "registry+https://github.com/rust-lang/crates.io-index"
193
+ dependencies = [
194
+ "serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
195
+ ]
196
+
197
+ [[package]]
198
+ name = "trybuild"
199
+ version = "1.0.28"
200
+ source = "registry+https://github.com/rust-lang/crates.io-index"
201
+ dependencies = [
202
+ "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
203
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
204
+ "serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)",
205
+ "serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
206
+ "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
207
+ "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
208
+ ]
209
+
97
210
  [[package]]
98
211
  name = "unicode-xid"
99
212
  version = "0.2.0"
100
213
  source = "registry+https://github.com/rust-lang/crates.io-index"
101
214
 
215
+ [[package]]
216
+ name = "version_check"
217
+ version = "0.9.2"
218
+ source = "registry+https://github.com/rust-lang/crates.io-index"
219
+
102
220
  [[package]]
103
221
  name = "winapi"
104
222
  version = "0.3.8"
@@ -113,6 +231,14 @@ name = "winapi-i686-pc-windows-gnu"
113
231
  version = "0.4.0"
114
232
  source = "registry+https://github.com/rust-lang/crates.io-index"
115
233
 
234
+ [[package]]
235
+ name = "winapi-util"
236
+ version = "0.1.5"
237
+ source = "registry+https://github.com/rust-lang/crates.io-index"
238
+ dependencies = [
239
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
240
+ ]
241
+
116
242
  [[package]]
117
243
  name = "winapi-x86_64-pc-windows-gnu"
118
244
  version = "0.4.0"
@@ -122,12 +248,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
122
248
  "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
123
249
  "checksum ctor 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3e061727ebef83bbccac7c27b9a5ff9fd83094d34cb20f4005440a9562a27de7"
124
250
  "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
251
+ "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
252
+ "checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
253
+ "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
125
254
  "checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
126
255
  "checksum pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
256
+ "checksum proc-macro-error 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678"
257
+ "checksum proc-macro-error-attr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53"
127
258
  "checksum proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8"
128
259
  "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
260
+ "checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
261
+ "checksum serde 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)" = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d"
262
+ "checksum serde_derive 1.0.111 (registry+https://github.com/rust-lang/crates.io-index)" = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250"
263
+ "checksum serde_json 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)" = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226"
129
264
  "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
265
+ "checksum syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a"
266
+ "checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
267
+ "checksum toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
268
+ "checksum trybuild 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "39e3183158b2c8170db33b8b3a90ddc7b5f380d15b50794d22c1fa9c61b47249"
130
269
  "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
270
+ "checksum version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
131
271
  "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
132
272
  "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
273
+ "checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
133
274
  "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
README.md CHANGED
@@ -34,22 +34,12 @@ ergonomics or speed.
34
34
 
35
35
  ## Usage
36
36
 
37
- > Note: `render` needs the `nightly` Rust compiler, for now, so it will have hygienic macros.
38
-
39
- This means you will need to add the following feature flag in the root of your `lib.rs`/`main.rs`:
40
-
41
- ```rust
42
- #![feature(proc_macro_hygiene)]
43
- ```
44
-
45
37
  ### Simple HTML rendering
46
38
 
47
39
  In order to render a simple HTML fragment into a `String`, use the `rsx!` macro to generate a
48
40
  component tree, and call `render` on it:
49
41
 
50
42
  ```rust
51
- #![feature(proc_macro_hygiene)]
52
-
53
43
  use render::{rsx, Render};
54
44
 
55
45
  let tree = rsx! {
@@ -72,8 +62,6 @@ use un-escaped values so you can dangerously insert raw HTML, use the `raw!` mac
72
62
  string:
73
63
 
74
64
  ```rust
75
- #![feature(proc_macro_hygiene)]
76
-
77
65
  use render::{html, raw};
78
66
 
79
67
  let tree = html! {
@@ -95,8 +83,6 @@ In order to build up components from other components or HTML nodes, you can use
95
83
  macro, which generates a `Render` component tree:
96
84
 
97
85
  ```rust
98
- #![feature(proc_macro_hygiene)]
99
-
100
86
  use render::{component, rsx, html};
101
87
 
102
88
  #[component]
@@ -148,8 +134,6 @@ your libraries.
148
134
  #### Full example
149
135
 
150
136
  ```rust
151
- #![feature(proc_macro_hygiene)]
152
-
153
137
  // A simple HTML 5 doctype declaration
154
138
  use render::html::HTML5Doctype;
155
139
  use render::{
render/src/fragment.rs CHANGED
@@ -7,7 +7,6 @@ use std::fmt::{Result, Write};
7
7
  /// in a RSX fashion
8
8
  ///
9
9
  /// ```rust
10
- /// # #![feature(proc_macro_hygiene)]
11
10
  /// # use pretty_assertions::assert_eq;
12
11
  /// # use render_macros::html;
13
12
  /// let result = html! {
render/src/html.rs CHANGED
@@ -6,7 +6,6 @@ use std::fmt::{Result, Write};
6
6
  /// HTML 5 doctype declaration
7
7
  ///
8
8
  /// ```rust
9
- /// # #![feature(proc_macro_hygiene)]
10
9
  /// # use pretty_assertions::assert_eq;
11
10
  /// # use render::html::HTML5Doctype;
12
11
  /// # use render::html;
render/src/lib.rs CHANGED
@@ -32,21 +32,12 @@
32
32
  //!
33
33
  //! # Usage
34
34
  //!
35
- //! > Note: `render` needs the `nightly` Rust compiler, for now, so it will have hygienic macros.
36
- //!
37
- //! This means you will need to add the following feature flag in the root of your `lib.rs`/`main.rs`:
38
- //!
39
- //! ```rust
40
- //! #![feature(proc_macro_hygiene)]
41
- //! ```
42
- //!
43
35
  //! ## Simple HTML rendering
44
36
  //!
45
37
  //! In order to render a simple HTML fragment into a `String`, use the `rsx!` macro to generate a
46
38
  //! component tree, and call `render` on it:
47
39
  //!
48
40
  //! ```rust
49
- //! #![feature(proc_macro_hygiene)]
50
41
  //! # use pretty_assertions::assert_eq;
51
42
  //!
52
43
  //! use render::{rsx, Render};
@@ -71,7 +62,6 @@
71
62
  //! string:
72
63
  //!
73
64
  //! ```rust
74
- //! #![feature(proc_macro_hygiene)]
75
65
  //! # use pretty_assertions::assert_eq;
76
66
  //!
77
67
  //! use render::{html, raw};
@@ -95,7 +85,6 @@
95
85
  //! macro, which generates a `Render` component tree:
96
86
  //!
97
87
  //! ```rust
98
- //! #![feature(proc_macro_hygiene)]
99
88
  //! # use pretty_assertions::assert_eq;
100
89
  //!
101
90
  //! use render::{component, rsx, html};
@@ -122,8 +111,6 @@
122
111
  //! ### Full example
123
112
  //!
124
113
  //! ```rust
125
- //! #![feature(proc_macro_hygiene)]
126
- //!
127
114
  //! // A simple HTML 5 doctype declaration
128
115
  //! use render::html::HTML5Doctype;
129
116
  //! use render::{
@@ -177,8 +164,6 @@
177
164
  //! # assert_eq!(actual, expected);
178
165
  //! ```
179
166
 
180
- #![feature(proc_macro_hygiene)]
181
-
182
167
  pub mod fragment;
183
168
  pub mod html;
184
169
  pub mod html_escaping;
render_macros/Cargo.toml CHANGED
@@ -19,6 +19,7 @@ proc-macro = true
19
19
  syn = { version = "1.0", features = ["full"] }
20
20
  quote = "1.0"
21
21
  proc-macro2 = "1.0"
22
+ proc-macro-error = "1.0"
22
23
 
23
24
  [dev-dependencies]
24
25
  render = { path = "../render", version = "0.3" }
render_macros/src/element_attributes.rs CHANGED
@@ -1,5 +1,6 @@
1
1
  use crate::children::Children;
2
2
  use crate::element_attribute::ElementAttribute;
3
+ use proc_macro_error::emit_error;
3
4
  use quote::{quote, ToTokens};
4
5
  use std::collections::HashSet;
5
6
  use syn::ext::IdentExt;
@@ -43,7 +44,7 @@ impl ElementAttributes {
43
44
  .filter_map(|attribute| match attribute.validate(is_custom_element) {
44
45
  Ok(x) => Some(x),
45
46
  Err(err) => {
46
- err.span().unwrap().error(err.to_string()).emit();
47
+ emit_error!(err.span(), "Invalid attribute: {}", err);
47
48
  None
48
49
  }
49
50
  })
@@ -60,11 +61,11 @@ impl Parse for ElementAttributes {
60
61
  let attribute = input.parse::<ElementAttribute>()?;
61
62
  let ident = attribute.ident();
62
63
  if attributes.contains(&attribute) {
63
- let error_message = format!(
64
+ emit_error!(
65
+ ident.span(),
64
66
  "There is a previous definition of the {} attribute",
65
67
  quote!(#ident)
66
68
  );
67
- ident.span().unwrap().warning(error_message).emit();
68
69
  }
69
70
  attributes.insert(attribute);
70
71
  }
render_macros/src/function_component.rs CHANGED
@@ -1,4 +1,5 @@
1
1
  use proc_macro::TokenStream;
2
+ use proc_macro_error::emit_error;
2
3
  use quote::quote;
3
4
  use syn::spanned::Spanned;
4
5
 
@@ -25,7 +26,7 @@ pub fn create_function_component(f: syn::ItemFn) -> TokenStream {
25
26
  .filter_map(|argument| match argument {
26
27
  syn::FnArg::Typed(typed) => Some(typed),
27
28
  syn::FnArg::Receiver(rec) => {
28
- rec.span().unwrap().error("Don't use `self` on components");
29
+ emit_error!(rec.span(), "Don't use `self` on components");
29
30
  None
30
31
  }
31
32
  })
render_macros/src/lib.rs CHANGED
@@ -1,5 +1,3 @@
1
- #![feature(proc_macro_diagnostic)]
2
-
3
1
  extern crate proc_macro;
4
2
 
5
3
  mod child;
@@ -12,6 +10,7 @@ mod tags;
12
10
 
13
11
  use element::Element;
14
12
  use proc_macro::TokenStream;
13
+ use proc_macro_error::proc_macro_error;
15
14
  use quote::quote;
16
15
  use syn::parse_macro_input;
17
16
 
@@ -22,7 +21,6 @@ use syn::parse_macro_input;
22
21
  /// ### Simple HTML elements start with a lowercase
23
22
  ///
24
23
  /// ```rust
25
- /// # #![feature(proc_macro_hygiene)]
26
24
  /// # use pretty_assertions::assert_eq;
27
25
  /// # use render_macros::html;
28
26
  /// let rendered = html! { <div id={"main"}>{"Hello"}</div> };
@@ -32,7 +30,6 @@ use syn::parse_macro_input;
32
30
  /// ### Custom components start with an uppercase
33
31
  ///
34
32
  /// ```rust
35
- /// # #![feature(proc_macro_hygiene)]
36
33
  /// # use pretty_assertions::assert_eq;
37
34
  /// # use render_macros::{html, rsx};
38
35
  /// use render::Render;
@@ -54,7 +51,6 @@ use syn::parse_macro_input;
54
51
  /// ### Values are always surrounded by curly braces
55
52
  ///
56
53
  /// ```rust
57
- /// # #![feature(proc_macro_hygiene)]
58
54
  /// # use render_macros::html;
59
55
  /// # use pretty_assertions::assert_eq;
60
56
  /// let rendered = html! {
@@ -67,7 +63,6 @@ use syn::parse_macro_input;
67
63
  /// ### HTML entities can accept dashed-separated value
68
64
  ///
69
65
  /// ```rust
70
- /// # #![feature(proc_macro_hygiene)]
71
66
  /// # use render_macros::html;
72
67
  /// # use pretty_assertions::assert_eq;
73
68
  /// let rendered = html! {
@@ -80,7 +75,6 @@ use syn::parse_macro_input;
80
75
  /// ### Custom components can't accept dashed-separated values
81
76
  ///
82
77
  /// ```compile_fail
83
- /// # #![feature(proc_macro_hygiene)]
84
78
  /// # use render_macros::html;
85
79
  /// // This will fail the compilation:
86
80
  /// let rendered = html! {
@@ -93,7 +87,6 @@ use syn::parse_macro_input;
93
87
  /// `value={value}` like Rust's punning
94
88
  ///
95
89
  /// ```rust
96
- /// # #![feature(proc_macro_hygiene)]
97
90
  /// # use render_macros::html;
98
91
  /// # use pretty_assertions::assert_eq;
99
92
  /// let class = "someclass";
@@ -108,7 +101,6 @@ use syn::parse_macro_input;
108
101
  /// ### Punning is not supported for dashed-delimited attributes
109
102
  ///
110
103
  /// ```compile_fail
111
- /// # #![feature(proc_macro_hygiene)]
112
104
  /// # use render_macros::html;
113
105
  ///
114
106
  /// let rendered = html! {
@@ -118,6 +110,7 @@ use syn::parse_macro_input;
118
110
  /// assert_eq!(rendered, r#"<div class="some_class"/>"#);
119
111
  /// ```
120
112
  #[proc_macro]
113
+ #[proc_macro_error]
121
114
  pub fn html(input: TokenStream) -> TokenStream {
122
115
  let el = proc_macro2::TokenStream::from(rsx(input));
123
116
  let result = quote! { ::render::Render::render(#el) };
@@ -126,6 +119,7 @@ pub fn html(input: TokenStream) -> TokenStream {
126
119
 
127
120
  /// Generate a renderable component tree, before rendering it
128
121
  #[proc_macro]
122
+ #[proc_macro_error]
129
123
  pub fn rsx(input: TokenStream) -> TokenStream {
130
124
  let el = parse_macro_input!(input as Element);
131
125
  let result = quote! { #el };
@@ -139,7 +133,6 @@ pub fn rsx(input: TokenStream) -> TokenStream {
139
133
  /// [`String`](std::string::String):
140
134
  ///
141
135
  /// ```rust
142
- /// # #![feature(proc_macro_hygiene)]
143
136
  /// # use render_macros::{component, rsx};
144
137
  /// #
145
138
  /// #[component]
@@ -151,7 +144,6 @@ pub fn rsx(input: TokenStream) -> TokenStream {
151
144
  /// Practically, this is exactly the same as using the [Render](../render/trait.Render.html) trait:
152
145
  ///
153
146
  /// ```rust
154
- /// # #![feature(proc_macro_hygiene)]
155
147
  /// # use render_macros::{component, rsx, html};
156
148
  /// # use render::Render;
157
149
  /// # use pretty_assertions::assert_eq;
@@ -181,6 +173,7 @@ pub fn rsx(input: TokenStream) -> TokenStream {
181
173
  /// # assert_eq!(from_fn, from_struct);
182
174
  /// ```
183
175
  #[proc_macro_attribute]
176
+ #[proc_macro_error]
184
177
  pub fn component(_attr: TokenStream, item: TokenStream) -> TokenStream {
185
178
  let f = parse_macro_input!(item as syn::ItemFn);
186
179
  function_component::create_function_component(f)
render_macros/src/tags.rs CHANGED
@@ -1,4 +1,5 @@
1
1
  use crate::element_attributes::ElementAttributes;
2
+ use proc_macro_error::abort;
2
3
  use quote::quote;
3
4
  use syn::parse::{Parse, ParseStream, Result};
4
5
  use syn::spanned::Spanned;
@@ -55,8 +56,11 @@ impl ClosingTag {
55
56
  let self_path = &self.name;
56
57
  let self_path_str = quote!(#self_path).to_string();
57
58
  if self_path_str != open_tag_path_str {
59
+ abort!(
60
+ self.name.span(),
58
- let error_message = format!("Expected closing tag for: <{}>", &open_tag_path_str);
61
+ "Expected closing tag for: <{}>",
59
- self.name.span().unwrap().error(error_message).emit();
62
+ &open_tag_path_str
63
+ );
60
64
  }
61
65
  }
62
66
  }
render_tests/Cargo.toml CHANGED
@@ -13,4 +13,4 @@ render = { path = "../render" }
13
13
 
14
14
  [dev-dependencies]
15
15
  pretty_assertions = "0.6"
16
-
16
+ trybuild = "1.0"
render_tests/src/lib.rs CHANGED
@@ -1,4 +1,8 @@
1
+ #[test]
2
+ fn ui() {
1
- #![feature(proc_macro_hygiene)]
3
+ let t = trybuild::TestCases::new();
4
+ t.compile_fail("ui/fail/*.rs");
5
+ }
2
6
 
3
7
  #[test]
4
8
  pub fn works_with_dashes() {
render_tests/ui/fail/unclosed-tag-complex.rs ADDED
@@ -0,0 +1,14 @@
1
+ use render::html;
2
+
3
+ fn main() {
4
+ html! {
5
+ <div>
6
+ <h1>{"A list"}</h1>
7
+ <hr />
8
+ <ul>
9
+ <li>{"1"}</li>
10
+ <li>
11
+ </ul>
12
+ </div>
13
+ };
14
+ }
render_tests/ui/fail/unclosed-tag-complex.stderr ADDED
@@ -0,0 +1,5 @@
1
+ error: Expected closing tag for: <li>
2
+ --> $DIR/unclosed-tag-complex.rs:11:11
3
+ |
4
+ 11 | </ul>
5
+ | ^^
render_tests/ui/fail/unclosed-tag.rs ADDED
@@ -0,0 +1,9 @@
1
+ use render::html;
2
+
3
+ fn main() {
4
+ html! {
5
+ <ul>
6
+ <li>
7
+ </ul>
8
+ };
9
+ }
render_tests/ui/fail/unclosed-tag.stderr ADDED
@@ -0,0 +1,5 @@
1
+ error: Expected closing tag for: <li>
2
+ --> $DIR/unclosed-tag.rs:7:9
3
+ |
4
+ 7 | </ul>
5
+ | ^^
render_tests/ui/fail/unexpected-attribute.rs ADDED
@@ -0,0 +1,10 @@
1
+ use render::{component, html, rsx};
2
+
3
+ #[component]
4
+ fn Heading<'title>(title: &'title str) {
5
+ rsx! { <h1>{title}</h1> }
6
+ }
7
+
8
+ fn main() {
9
+ html! { <Heading t={"Hello world!"} /> };
10
+ }
render_tests/ui/fail/unexpected-attribute.stderr ADDED
@@ -0,0 +1,7 @@
1
+ error[E0560]: struct `Heading<'_>` has no field named `t`
2
+ --> $DIR/unexpected-attribute.rs:9:22
3
+ |
4
+ 9 | html! { <Heading t={"Hello world!"} /> };
5
+ | ^ `Heading<'_>` does not have this field
6
+ |
7
+ = note: available fields are: `title`