use proc_macro::TokenStream;
use quote::quote;
use syn::{DeriveInput, parse_macro_input};
#[proc_macro_derive(FromClient)]
pub fn derive_from_client(item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as DeriveInput);
let struct_name = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let syn::Data::Struct(syn::DataStruct {
fields: syn::Fields::Named(fields),
..
}) = &input.data
else {
return syn::Error::new_spanned(
&input,
"FromClient can only be derived for structs with named fields",
)
.to_compile_error()
.into();
};
let field_inits = fields.named.iter().filter_map(|f| {
let field_name = f.ident.as_ref()?;
let field_type = &f.ty;
Some(quote! {
#field_name: ::bitwarden_core::client::FromClientPart::<#field_type>::get_part(client)
})
});
let expanded = quote! {
impl #impl_generics ::bitwarden_core::client::FromClient for #struct_name #ty_generics #where_clause {
fn from_client(client: &::bitwarden_core::Client) -> Self {
Self {
#(#field_inits),*
}
}
}
};
TokenStream::from(expanded)
}