1 extern crate proc_macro;
2 use proc_macro::*;
3
4 #[proc_macro]
a_proc_macro(_item: TokenStream) -> TokenStream5 pub fn a_proc_macro(_item: TokenStream) -> TokenStream {
6 "fn ex() { foobar::f(); }".parse().unwrap()
7 }
8
9 // inserts foobar::f() to the end of the function
10 #[proc_macro_attribute]
an_attr_macro(attr: TokenStream, item: TokenStream) -> TokenStream11 pub fn an_attr_macro(attr: TokenStream, item: TokenStream) -> TokenStream {
12 let new_call: TokenStream = "foobar::f();".parse().unwrap();
13
14 let mut tokens = item.into_iter();
15
16 let fn_tok = tokens.next().unwrap();
17 let ident_tok = tokens.next().unwrap();
18 let args_tok = tokens.next().unwrap();
19 let body = match tokens.next().unwrap() {
20 TokenTree::Group(g) => {
21 let new_g = Group::new(g.delimiter(), new_call);
22 let mut outer_g = Group::new(
23 g.delimiter(),
24 [TokenTree::Group(g.clone()), TokenTree::Group(new_g)].into_iter().collect(),
25 );
26
27 if attr.to_string() == "with_span" {
28 outer_g.set_span(g.span());
29 }
30
31 TokenTree::Group(outer_g)
32 }
33 _ => unreachable!(),
34 };
35
36 let tokens = vec![fn_tok, ident_tok, args_tok, body].into_iter().collect::<TokenStream>();
37
38 tokens
39 }
40