fluidity_derive/
lib.rs

1/*
2    Appellation: rs-sandbox-derive <library>
3    Creator: FL03 <jo3mccain@icloud.com>
4    Description:
5        ... Summary ...
6*/
7extern 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}