diff options
Diffstat (limited to 'engine-macros/src/reflection/struct_impl.rs')
| -rw-r--r-- | engine-macros/src/reflection/struct_impl.rs | 105 |
1 files changed, 64 insertions, 41 deletions
diff --git a/engine-macros/src/reflection/struct_impl.rs b/engine-macros/src/reflection/struct_impl.rs index ce1086b..58046fe 100644 --- a/engine-macros/src/reflection/struct_impl.rs +++ b/engine-macros/src/reflection/struct_impl.rs @@ -2,62 +2,85 @@ use quote::quote; use crate::reflection::default_value::gen_get_default_value_fn; use crate::reflection::field::{generate as generate_field, ReflectionFieldGenOptions}; -use crate::util::{find_engine_crate_path, syn_path, SynPathExt}; +use crate::reflection::options_attr::OptionsAttr; +use crate::util::find_engine_crate_path; -pub fn generate(input: syn::ItemStruct) -> proc_macro2::TokenStream +pub fn generate(input: syn::ItemStruct, options: OptionsAttr) + -> proc_macro2::TokenStream { let engine_crate_path = find_engine_crate_path().unwrap(); - let input_ident = input.ident; - - let type_reflection_optional = input.generics.params.is_empty(); + if input.generics.params.is_empty() { + return gen_impl(&input, None, &engine_crate_path); + } - let mut generics = input.generics; + let impls = options + .impl_with_generics + .into_iter() + .map(|generic_args| gen_impl(&input, Some(&generic_args), &engine_crate_path)); - for type_param in generics.type_params_mut() { - type_param - .bounds - .push(syn::TypeParamBound::Trait(syn::TraitBound { - paren_token: None, - modifier: syn::TraitBoundModifier::None, - lifetimes: None, - path: engine_crate_path.join(syn_path!(reflection::Reflection)), - })); + quote! { + #(#impls)* } +} - let (impl_generics, type_generics, where_clause) = generics.split_for_impl(); - - let fields = input - .fields - .into_iter() - .enumerate() - .map(|(field_index, field)| { - generate_field( - &field, - field_index, - &engine_crate_path, - ReflectionFieldGenOptions { - field_vis_override: None, - gen_get_byte_offset: &|field| { - if let Some(field_ident) = &field.ident { - quote! { std::mem::offset_of!(Self, #field_ident) } - } else { - quote! { std::mem::offset_of!(Self, #field_index) } - } - }, - type_reflection_optional, +fn gen_impl( + input: &syn::ItemStruct, + generic_args: Option<&syn::AngleBracketedGenericArguments>, + engine_crate_path: &syn::Path, +) -> proc_macro2::TokenStream +{ + let fields = input.fields.iter().enumerate().map(|(field_index, field)| { + generate_field( + &field, + field_index, + &engine_crate_path, + ReflectionFieldGenOptions { + field_vis_override: None, + gen_get_byte_offset: &|field| { + if let Some(field_ident) = &field.ident { + quote! { std::mem::offset_of!(Self, #field_ident) } + } else { + quote! { std::mem::offset_of!(Self, #field_index) } + } }, - ) - }); + }, + ) + }); + + let get_default_value_fn = gen_get_default_value_fn(&input.ident, generic_args); + + let input_ident = &input.ident; - let get_default_value_fn = gen_get_default_value_fn(&input_ident, &type_generics); + let generics_type_aliases = input + .generics + .type_params() + .zip( + generic_args + .iter() + .map(|generic_args| &generic_args.args) + .flatten() + .flat_map(|generic_arg| match generic_arg { + syn::GenericArgument::Type(ty) => Some(ty), + _ => None, + }), + ) + .map(|(type_param, generic_arg_type)| { + let type_param_ident = &type_param.ident; + + quote! { + type #type_param_ident = #generic_arg_type; + } + }); quote! { - unsafe impl #impl_generics #engine_crate_path::reflection::Reflection for - #input_ident #type_generics #where_clause + unsafe impl #engine_crate_path::reflection::Reflection for + #input_ident #generic_args { const TYPE_REFLECTION: &#engine_crate_path::reflection::Type = &const { + #(#generics_type_aliases)* + #engine_crate_path::reflection::Type::Struct( #engine_crate_path::reflection::Struct { fields: &[ |
