extern crate proc_macro; use proc_macro::*; #[proc_macro] pub fn a_proc_macro(_item: TokenStream) -> TokenStream { "fn ex() { foobar::f(); }".parse().unwrap() } // inserts foobar::f() to the end of the function #[proc_macro_attribute] pub fn an_attr_macro(attr: TokenStream, item: TokenStream) -> TokenStream { let new_call: TokenStream = "foobar::f();".parse().unwrap(); let mut tokens = item.into_iter(); let fn_tok = tokens.next().unwrap(); let ident_tok = tokens.next().unwrap(); let args_tok = tokens.next().unwrap(); let body = match tokens.next().unwrap() { TokenTree::Group(g) => { let new_g = Group::new(g.delimiter(), new_call); let mut outer_g = Group::new( g.delimiter(), [TokenTree::Group(g.clone()), TokenTree::Group(new_g)].into_iter().collect(), ); if attr.to_string() == "with_span" { outer_g.set_span(g.span()); } TokenTree::Group(outer_g) } _ => unreachable!(), }; let tokens = vec![fn_tok, ident_tok, args_tok, body].into_iter().collect::(); tokens }