@@ -157,8 +157,7 @@ define new items given the token stream of a [struct], [enum], or [union]. They
157
157
also define derive mode helper attributes.
158
158
159
159
Custom derivers are defined by a [ public] [ function] with the ` proc_maco_derive `
160
- attribute that takes a single input of the type [ ` TokenStream ` ] and returns a
161
- [ ` TokenStream ` ] .
160
+ attribute and a signature of ` (TokenStream) -> TokenStream ` .
162
161
163
162
The input [ ` TokenStream ` ] is the token stream of the item that has the ` derive `
164
163
attribute on it. The output [ ` TokenStream ` ] must be a set of items that are
@@ -230,85 +229,91 @@ struct Struct {
230
229
231
230
### Attribute macros
232
231
233
- Attribute macros allow you to define a new ` #[attr] ` -style attribute which can
234
- be attached to items and generate wrappers and such. These macros are defined
235
- like:
232
+ * Attribute macros* define new [ attributes] which can be attached to [ items] .
236
233
237
- ``` rust,ignore
238
- #[proc_macro_attribute]
239
- pub fn foo(attr: TokenStream, input: TokenStream) -> TokenStream {
240
- // ...
241
- }
242
- ```
234
+ Attribute macros are defined by a [ public] [ function] with the
235
+ ` proc_macro_attribute ` attribute that a signature of `(TokenStream, TokenStream)
236
+ -> TokenStream` . The first [ ` TokenStream`] is the attribute's metaitems, not
237
+ including the delimiters. If the attribute is written without a metaitem, the
238
+ attribute [ ` TokenStream ` ] is empty. The second [ ` TokenStream ` ] is of the rest of
239
+ the item including other attributes on the item. The returned [ ` TokenStream ` ]
240
+ replaces the item. It may contain an arbitrary number of items. The returned
241
+ [ ` TokenStream ` ] cannot include any [ macro] definitions.
242
+
243
+ For example, this attribute macro takes the input stream and returns it as is,
244
+ effectively being the no-op of attributes.
245
+
246
+ ``` rust
247
+ #![crate_type = " proc_macro" ]
243
248
244
- The ` #[proc_macro_attribute] ` indicates that this macro is an attribute macro
245
- and can only be invoked like ` #[foo] ` . The name of the function here will be the
246
- name of the attribute as well.
249
+ extern crate proc_macro;
247
250
248
- The first input, ` attr ` , is the arguments to the attribute provided. The second
249
- argument, ` item ` , is the item that the attribute is attached to.
251
+ use proc_macro :: TokenStream ;
250
252
251
- Like with bang macros at the beginning (and unlike derive macros), the return
252
- value here * replaces* the input ` item ` .
253
+ #[proc_macro_attribute]
254
+ pub fn return_as_is (_attr : TokenStream , item : TokenStream ) -> TokenStream {
255
+ item
256
+ }
257
+ ```
253
258
254
- Let's see this attribute in action:
259
+ This following example shows the stringified [ ` TokenStream ` s] that the attribute
260
+ macros see. The output will show in the output of the compiler. The output is
261
+ shown in the comments after the function prefixed with "out:".
255
262
256
263
``` rust,ignore
257
264
// my-macro/src/lib.rs
258
- extern crate proc_macro;
259
- use proc_macro::* ;
265
+ # extern crate proc_macro;
266
+ # use proc_macro::TokenStream ;
260
267
261
268
#[proc_macro_attribute]
262
- pub fn foo (attr: TokenStream, input: TokenStream) -> TokenStream {
263
- println!("attr: {} ", attr.to_string());
264
- println!("input: {}" , input.to_string());
269
+ pub fn show_streams (attr: TokenStream, input: TokenStream) -> TokenStream {
270
+ println!("attr: \"{}\" ", attr.to_string());
271
+ println!("item: \"{}\"' , input.to_string());
265
272
item
266
273
}
267
274
```
268
275
269
- and invoke it as:
270
-
271
276
``` rust,ignore
272
- // src/main .rs
277
+ // src/lib .rs
273
278
extern crate my_macro;
274
279
275
- use my_macro::foo ;
280
+ use my_macro::show_streams ;
276
281
277
- #[foo]
282
+ // Example: Basic function
283
+ #[show_streams]
278
284
fn invoke1() {}
285
+ // out: attr: ""
286
+ // out: item: "fn invoke1() { }"
279
287
280
- #[foo(bar)]
288
+ // Example: Attribute has a metaitem
289
+ #[show_streams(bar)]
281
290
fn invoke2() {}
291
+ // out: attr: "bar"
292
+ // out: item: "fn invoke2() {}"
282
293
283
- #[foo(crazy custom syntax)]
294
+ // Example: Multiple words in metaitem
295
+ #[show_streams(multiple words)]
284
296
fn invoke3() {}
297
+ // out: attr: "multiple words"
298
+ // out: item: "fn invoke3() {}"
285
299
286
- #[foo { delimiters }]
300
+ // Example:
301
+ #[show_streams { delimiters }]
287
302
fn invoke4() {}
288
-
289
- fn main() {
290
- // ...
291
- }
303
+ // out: "delimiters"
304
+ // out: "fn invoke4() {}"
292
305
```
293
306
294
- compiled as:
295
-
296
- ```
297
- attr:
298
- input: fn invoke1() { }
299
- attr: bar
300
- input: fn invoke2() { }
301
- attr: crazy custom syntax
302
- input: fn invoke3() { }
303
- attr: delimiters
304
- input: fn invoke4() { }
305
- ```
306
-
307
- Here we can see how the arguments to the attribute show up in the ` attr `
308
- argument. Notably these arguments do not include the delimiters used to enclose
309
- the arguments (like procedural bang macros. Furthermore we can see the item
310
- continue to operate on it, either replacing it or augmenting it.
311
-
312
307
[ `TokenStream` ] : ../proc_macro/struct.TokenStream.html
308
+ [ `TokenStream`s ] : ../proc_macro/struct.TokenStream.html
309
+ [ `derive` ] : attributes.html#derive
313
310
[ `proc_macro` crate ] : ../proc_macro/index.html
314
- [ crate type ] : linkage.html
311
+ [ attributes ] : attributes.html
312
+ [ custom attributes ] : attributes.html
313
+ [ crate type ] : linkage.html
314
+ [ item ] : items.html
315
+ [ function ] : items/functions.html
316
+ [ macro ] : macros.html
317
+ [ module ] : items/modules.html
318
+ [ procedural macro tutorial ] : ../book/2018-edition/appendix-04-macros.html#procedural-macros-for-custom-derive
319
+ [ public ] : visibility-and-privacy.html
0 commit comments