derive_name_table/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
extern crate proc_macro;

use self::proc_macro::TokenStream;
use quote::quote;

use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields};


#[proc_macro_derive(NameTable, attributes(table_name))]
pub fn derive_name_table(item: TokenStream) -> TokenStream {
    let tokens = parse_macro_input!(item as DeriveInput);
    let struct_name = tokens.ident;
    let atr = tokens.attrs[0].tokens.to_string().replace("= ", "");
    let fields = match &tokens.data {
        Data::Struct(DataStruct {
                         fields: Fields::Named(fields),
                         ..
                     }) => &fields.named,
        _ => panic!("expected a struct with named fields"),
    };
    let field_name = fields.iter().map(|field|
        &field.ident
    );
    TokenStream::from(quote! {
        impl NameTable for #struct_name  {
            fn get_table_name() -> String {
                String::from(#atr)
            }
            fn get_fields() -> Vec<String> {
                vec![ #( String::from(stringify!(#field_name)) ),* ]
            }
        }

    })

}