use quote::quote;
pub fn derive(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input: syn::DeriveInput = syn::parse_macro_input!(tokens);
let items = if let syn::Data::Struct(syn::DataStruct {
struct_token: _,
fields: syn::Fields::Named(fields),
semi_token: _,
}) = input.data
{
fields
.named
.into_iter()
.map(|f| (f.ident.unwrap(), f.ty))
.collect::<Vec<_>>()
} else {
panic!("Can only derive Schema on data structs with named fields!");
};
let item_ident = input.ident;
let visit_items = items.iter().map(|field| {
let item_type = &field.1;
quote! {
<#item_type as ::microrm::schema::DatabaseItem>::accept_item_visitor(&<#item_type as Default>::default(), v);
}
});
quote! {
impl ::microrm::schema::DatabaseItem for #item_ident {
fn accept_item_visitor(&self, v: &mut impl ::microrm::schema::DatabaseItemVisitor) {
use ::microrm::schema::DatabaseItem;
#(#visit_items)*
}
}
}
.into()
}