1extern crate proc_macro;
11
12use proc_macro::TokenStream;
13use quote::quote;
14
15fn element_name_macro(ast: &syn::DeriveInput) -> TokenStream {
16 let name = &ast.ident;
17 let mut elem_name = ast.ident.to_string();
18 let (impl_generics, type_generics, _) = &ast.generics.split_for_impl();
19
20 if ast.attrs.len() > 0 {
21 let attribute = &ast.attrs[0];
22 match attribute.parse_meta() {
23 Ok(syn::Meta::List(meta)) => {
24 if meta.nested.len() > 0 {
25 elem_name = match &meta.nested[0] {
26 syn::NestedMeta::Meta(syn::Meta::NameValue(v)) => match &v.lit {
27 syn::Lit::Str(lit) => lit.value(),
28 _ => panic!("Invalid element_name attribute"),
29 },
30 _ => panic!("Invalid element_name attribute"),
31 };
32 } else {
33 panic!("Invalid element_name attribute");
34 }
35 }
36 _ => panic!("Invalid element_name attribute"),
37 };
38 }
39
40 let implement = quote! {
41 impl #impl_generics ElementName for #name #type_generics {
42 fn element_name(&self) -> &'static str {
43 #elem_name
44 }
45 }
46 };
47 implement.into()
48}
49
50#[proc_macro_derive(ElementName, attributes(element_name))]
51pub fn element_name_derive(input: TokenStream) -> TokenStream {
52 let ast = syn::parse(input).expect("Error while parsing ElementName macro input");
53
54 element_name_macro(&ast)
55}