use proc_macro::TokenStream;
use quote::quote;
use syn::{
parse_macro_input, Data::Struct, DataStruct, DeriveInput, Fields::Named,
FieldsNamed,
};
#[proc_macro_attribute]
pub fn verbose(_attr: TokenStream, item: TokenStream) -> TokenStream {
let ast = parse_macro_input!(item as DeriveInput);
let vis = ast.vis;
let name = ast.ident;
let attrs = &ast.attrs;
let Struct(DataStruct {
fields:
Named(FieldsNamed {
ref named,
..
}),
..
}) = ast.data
else {
unimplemented!("only works on structs");
};
let builder_fields = named.iter().map(|f| {
let name = &f.ident;
let ty = &f.ty;
let attrs = &f.attrs;
let vis = &f.vis;
quote! {
#(#attrs)*
#vis #name: #ty
}
});
let decorated = quote! {
#(#attrs)*
#vis struct #name {
#[clap(short, long, action = ::clap::ArgAction::Count, global = true)]
#vis verbose: u8,
#(#builder_fields,)*
}
};
decorated.into()
}