Cargo.toml:
[package] name = "customderive" version = "0.1.1" [lib] proc-macro=true [dependencies] quote="^0.3.12" syn="^0.11.4"
src/lib.rs:
#![crate_type = "proc-macro"] extern crate proc_macro; use proc_macro::TokenStream; extern crate syn; #[macro_use] extern crate quote; #[proc_macro_derive(Hello)] pub fn qqq(input: TokenStream) -> TokenStream { let source = input.to_string(); println!("Normalized source code: {}", source); let ast = syn::parse_derive_input(&source).unwrap(); println!("Syn's AST: {:?}", ast); // {:#?} - pretty print let struct_name = &ast.ident; let quoted_code = quote!{ fn hello() { println!("Hello, {}!", stringify!(#struct_name)); } }; println!("Quoted code: {:?}", quoted_code); quoted_code.parse().unwrap() }
examples/hello.rs:
#[macro_use] extern crate customderive; #[derive(Hello)] struct Qqq; fn main(){ hello(); }
output:
$ cargo run --example hello
Compiling customderive v0.1.1 (file:///tmp/cd)
Normalized source code: struct Qqq;
Syn's AST: DeriveInput { ident: Ident("Qqq"), vis: Inherited, attrs: [], generics: Generics { lifetimes: [], ty_params: [], where_clause: WhereClause { predicates: [] } }, body: Struct(Unit) }
Quoted code: Tokens("fn hello ( ) { println ! ( \"Hello, {}!\" , stringify ! ( Qqq ) ) ; }")
warning: struct is never used: <snip>
Finished dev [unoptimized + debuginfo] target(s) in 3.79 secs
Running `target/x86_64-unknown-linux-gnu/debug/examples/hello`
Hello, Qqq!