summaryrefslogtreecommitdiff
path: root/engine-macros/src/reflection/struct_impl.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine-macros/src/reflection/struct_impl.rs')
-rw-r--r--engine-macros/src/reflection/struct_impl.rs105
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: &[