diff options
Diffstat (limited to 'engine-macros/src')
| -rw-r--r-- | engine-macros/src/reflection/enum_impl.rs | 8 | ||||
| -rw-r--r-- | engine-macros/src/reflection/struct_impl.rs | 72 |
2 files changed, 74 insertions, 6 deletions
diff --git a/engine-macros/src/reflection/enum_impl.rs b/engine-macros/src/reflection/enum_impl.rs index b637d9f..37abc34 100644 --- a/engine-macros/src/reflection/enum_impl.rs +++ b/engine-macros/src/reflection/enum_impl.rs @@ -356,20 +356,20 @@ fn generate_variants<'a>( #![allow(unreachable_code)] use std::any::Any; - use #engine_crate_path::reflection::EnumVariantGetFieldError; + use #engine_crate_path::reflection::GetError; let target = target .downcast_mut::<Self>() - .ok_or(EnumVariantGetFieldError::WrongTargetType)?; + .ok_or(GetError::WrongTargetType)?; let #variant_pattern = target else { - return Err(EnumVariantGetFieldError::WrongTargetVariant); + return Err(GetError::WrongTargetEnumVariant); }; let field: &mut dyn Any = match field_index { #field_index_match_arms _ => { - return Err(EnumVariantGetFieldError::FieldIndexOutOfBounds); + return Err(GetError::IndexOutOfBounds); } }; diff --git a/engine-macros/src/reflection/struct_impl.rs b/engine-macros/src/reflection/struct_impl.rs index 4fbf88b..8617874 100644 --- a/engine-macros/src/reflection/struct_impl.rs +++ b/engine-macros/src/reflection/struct_impl.rs @@ -1,4 +1,4 @@ -use quote::quote; +use quote::{format_ident, quote}; use crate::reflection::default_value::gen_get_default_value_fn; use crate::reflection::field::{generate as generate_field, ReflectionFieldGenOptions}; @@ -73,12 +73,64 @@ fn gen_impl( } }); + let struct_pattern = match &input.fields { + syn::Fields::Unit => quote! { Self }, + syn::Fields::Named(syn::FieldsNamed { named: named_fields, .. }) => { + let field_idents = named_fields.iter().map(|field| { + let Some(field_ident) = &field.ident else { + unreachable!(); + }; + + field_ident + }); + + quote! { Self { #(#field_idents),* } } + } + syn::Fields::Unnamed(syn::FieldsUnnamed { unnamed: unnamed_fields, .. }) => { + let field_idents = unnamed_fields + .iter() + .enumerate() + .map(|(field_index, _)| format_ident!("field_{field_index}")); + + quote! { Self(#(#field_idents),*) } + } + }; + + let field_index_match_arms = match &input.fields { + syn::Fields::Unit => quote! {}, + syn::Fields::Named(syn::FieldsNamed { named: named_fields, .. }) => { + let match_arms = + named_fields.iter().enumerate().map(|(field_index, field)| { + let Some(field_ident) = &field.ident else { + unreachable!(); + }; + + quote! { #field_index => { #field_ident } } + }); + + quote! { #(#match_arms)* } + } + syn::Fields::Unnamed(syn::FieldsUnnamed { unnamed: unnamed_fields, .. }) => { + let match_arms = unnamed_fields.iter().enumerate().map(|(field_index, _)| { + let field_ident = format_ident!("field_{field_index}"); + + quote! { #field_index => { #field_ident } } + }); + + quote! { #(#match_arms)* } + } + }; + quote! { unsafe impl #engine_crate_path::reflection::Reflection for #input_ident #generic_args { const TYPE_REFLECTION: &#engine_crate_path::reflection::Type = &const { + use std::any::Any; + + use #engine_crate_path::reflection::GetError; + #(#generics_type_aliases)* #engine_crate_path::reflection::Type::Struct( @@ -89,7 +141,23 @@ fn gen_impl( get_default_value: || { #get_default_value_fn }, - cast_dyn_any: |ptr| ptr.cast::<Self>() + cast_dyn_any: |ptr| ptr.cast::<Self>(), + try_get_field_mut: |target, field_index| { + let target = target + .downcast_mut::<Self>() + .ok_or(GetError::WrongTargetType)?; + + let #struct_pattern = target; + + let field: &mut dyn Any = match field_index { + #field_index_match_arms + _ => { + return Err(GetError::IndexOutOfBounds); + } + }; + + Ok(field) + }, } ) }; |
