Hi,
I'd like to generate structs from other structs using a derive macro. Specifically I'd like to generate AUpdate from A like in the example below.
#[derive(Copy, Clone, UpdateStruct)]
pub(crate) struct A {
one: u32,
}
#[derive(Copy, Clone)]
pub(crate) struct B {
a_update: AUpdate,
}
pub fn main() {
let a = A { one: 10 };
let a_update = AUpdate { one_update: 10 };
}
I have a macro to do this (see below) but the issue I'm having is implementing / inheriting the derived traits for A (in this case Copy and Clone) so that AUpdate also implements them.
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, DeriveInput};
// Procedural macro definition
#[proc_macro_derive(UpdateStruct)]
pub fn derive_update(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident;
let visibility = input.vis;
let update_name = syn::Ident::new(&format!("{}Update", name), name.span());
// Extract the fields of the struct
let fields = if let syn::Data::Struct(data_struct) = input.data {
data_struct.fields
} else {
panic!("#[derive(UpdateStruct)] is only supported for structs");
};
let update_fields = fields.iter().filter_map(|field| {
if let Some(field_name) = &field.ident {
let field_type = &field.ty;
let updated_field_name =
syn::Ident::new(&format!("{}_update", field_name), field_name.span());
Some(quote! {
pub #updated_field_name : #field_type
})
} else {
None
}
});
let expanded = quote! {
// The generated AUpdate struct
#visibility struct #update_name {
#(#update_fields),*
}
};
expanded.into()
}
I can see that input has the attrs
field but I haven't been able to make any progress in using them. Any help would be greatly appreciated!
Many thanks