use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput, Ident};
#[proc_macro_derive(UID, attributes(uid, alias))]
pub fn derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let ident = input.ident.clone();
let parser = Parser::new(input).unwrap();
let expanded = parser.expand(&ident);
let a = quote! {
#expanded
};
proc_macro::TokenStream::from(a)
}
mod alias;
mod uid;
#[derive(Debug, Clone, Default)]
struct Parser {
pub uid_attrs: uid::Attributes,
pub alias_attrs: alias::Attributes,
}
impl Parser {
fn new(input: DeriveInput) -> syn::Result<Parser> {
let mut parser: Parser = Default::default();
for attr in input.attrs {
if attr.path().is_ident("uid") {
parser.uid_attrs = attr.parse_args()?;
}
if attr.path().is_ident("alias") {
parser.alias_attrs = attr.parse_args()?;
}
}
Ok(parser)
}
}
type Expanded = proc_macro2::TokenStream;
trait Expand {
fn expand(&self, ident: &Ident) -> Expanded;
}
impl Expand for Parser {
fn expand(&self, ident: &Ident) -> Expanded {
let uid = self.uid_attrs.expand(ident);
let alias = self.alias_attrs.expand(ident);
quote! {
#alias
#uid
}
}
}