use crate::helper::*;
struct StatenumArgs {
name: Option<Ident>,
}
impl Parse for StatenumArgs {
fn parse(input: ParseStream) -> Result<Self> {
let name = input.parse::<LitStr>().ok().map(|s| Ident::new(&s.value(), s.span()));
Ok(StatenumArgs { name })
}
}
pub fn _statenum(args: TokenStream, item: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as StatenumArgs);
let name = args.name.unwrap_or_else(|| Ident::new("State", Span::call_site()));
let input = parse_macro_input!(item as DeriveInput);
let visibility = &input.vis;
let data = match input.data {
Data::Enum(e) => e,
_ => panic!("statenum can only be used with enums"),
};
let structs = data.variants.iter().map(|variant| {
let struct_name = Ident::new(&format!("{}", variant.ident), variant.ident.span());
quote! {
#visibility struct #struct_name;
impl #name for #struct_name {}
}
});
let state_trait = quote! {
#visibility trait #name {}
};
let expanded = quote! {
#state_trait
#(#structs)*
};
TokenStream::from(expanded)
}