Skip to main content

autoschematic_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{Data, DeriveInput, Fields, parse_macro_input};
4
5#[proc_macro_derive(FieldTypes)]
6pub fn field_types(input: TokenStream) -> TokenStream {
7    let input = parse_macro_input!(input as DeriveInput);
8    let name = &input.ident;
9    let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
10
11    let fields = match &input.data {
12        Data::Struct(s) => &s.fields,
13        _ => panic!("FieldTypes only works on structs"),
14    };
15
16    let match_arms: Vec<_> = match fields {
17        Fields::Named(named) => named
18            .named
19            .iter()
20            .map(|f| {
21                let ident = f.ident.as_ref().unwrap();
22                let ty = &f.ty;
23                quote! {stringify!(#ident) => Some(stringify!(#ty)),}
24            })
25            .collect(),
26        _ => panic!("FieldTypes needs named fields"),
27    };
28
29    quote! {
30        // #[automatically_derived]
31        impl #impl_generics FieldTypes for #name #ty_generics #where_clause {
32            fn field_type<__Documented_T: AsRef<str>>(field_name: __Documented_T) -> Option<&'static str> {
33                // use phf;
34
35                // static PHF: phf::Map<&'static str, &'static str> = phf::phf_map! {
36                //     #(#phf_match_arms)*
37                // };
38                // PHF.get(field_name.as_ref()).copied()
39                match field_name.as_ref() {
40                    #(#match_arms)*
41                    _ => None,
42                }
43            }
44        }
45    }
46    .into()
47}