epp_client_macros/
lib.rs

1//! # Macros for the epp-client Library.
2//!
3//! ## Description
4//!
5//! `epp-client` is a client library for Internet domain registration and management for domain registrars.
6//! This macro crate contains a few macros to simplify serialization of generic types used in some places
7//! in the `epp-client` library
8//!
9
10extern 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}