1extern crate proc_macro;
8
9use proc_macro::TokenStream;
10use quote;
11use syn;
12
13#[proc_macro_derive(SampleFunction)]
14pub fn derive_sample_function(_item: TokenStream) -> TokenStream {
15 "fn sample() -> u16 { 18 }".parse().unwrap()
16}
17
18#[proc_macro_derive(Describe)]
19pub fn describe(input: TokenStream) -> TokenStream {
20 let syn::DeriveInput { ident, data, .. } = syn::parse_macro_input!(input);
21
22 let description = match data {
23 syn::Data::Struct(s) => match s.fields {
24 syn::Fields::Named(syn::FieldsNamed { named, .. }) => {
25 let idents = named.iter().map(|f| &f.ident);
26 format!(
27 "a struct with these named fields: {}",
28 quote::quote! {#(#idents), *}
29 )
30 }
31 syn::Fields::Unnamed(syn::FieldsUnnamed { unnamed, .. }) => {
32 let num_fields = unnamed.iter().count();
33 format!("a struct with {} unnamed fields", num_fields)
34 }
35 syn::Fields::Unit => format!("a unit struct"),
36 },
37 syn::Data::Enum(syn::DataEnum { variants, .. }) => {
38 let vs = variants.iter().map(|v| &v.ident);
39 format!("an enum with these variants: {}", quote::quote! {#(#vs),*})
40 }
41 syn::Data::Union(syn::DataUnion {
42 fields: syn::FieldsNamed { named, .. },
43 ..
44 }) => {
45 let idents = named.iter().map(|f| &f.ident);
46 format!(
47 "a union with these named fields: {}",
48 quote::quote! {#(#idents),*}
49 )
50 }
51 };
52
53 let output = quote::quote! {
54 impl #ident {
55 fn describe() -> String { format!("{} is {}.", stringify!(#ident), #description) }
56 }
57 };
58
59 output.into()
60}