summaryrefslogtreecommitdiff
path: root/engine-macros/src/reflection/enum_impl.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-07-05 00:40:35 +0200
committerHampusM <hampus@hampusmat.com>2026-07-05 00:40:35 +0200
commitd10552031890ec09937d1b7a0dea1e68b0daf79a (patch)
treed19ccf66e6fbb5246cacee0b553794113295eee8 /engine-macros/src/reflection/enum_impl.rs
parent7f529801932fa98967b4dc959d4e9bb79511ff79 (diff)
feat(engine): add try_write_new_to fn to enum variant reflection
Diffstat (limited to 'engine-macros/src/reflection/enum_impl.rs')
-rw-r--r--engine-macros/src/reflection/enum_impl.rs90
1 files changed, 90 insertions, 0 deletions
diff --git a/engine-macros/src/reflection/enum_impl.rs b/engine-macros/src/reflection/enum_impl.rs
index ea83681..baf1732 100644
--- a/engine-macros/src/reflection/enum_impl.rs
+++ b/engine-macros/src/reflection/enum_impl.rs
@@ -331,12 +331,102 @@ fn generate_variants<'a>(
}
};
+ let variant_field_vars = variant.fields.iter().enumerate().map(
+ |(variant_field_index, variant_field)| {
+ let var_ident = match variant_field.ident.as_ref() {
+ Some(field_ident) => format_ident!("field_{field_ident}"),
+ None => format_ident!("field_{}", variant_field_index),
+ };
+
+ let field_type = &variant_field.ty;
+
+ quote! {
+ let #var_ident = fields
+ .next()
+ .ok_or(EnumVariantWriteNewToError::TooFewFields)?
+ .downcast::<#field_type>()
+ .map_err(|_| EnumVariantWriteNewToError::WrongFieldType)?;
+ }
+ },
+ );
+
+ let variant_construction =
+ match &variant.fields {
+ syn::Fields::Unit => {
+ let variant_ident = &variant.ident;
+
+ quote! {
+ Self::#variant_ident
+ }
+ }
+ syn::Fields::Named(named_fields) => {
+ let variant_ident = &variant.ident;
+
+ let fields = named_fields.named.iter().map(|field| {
+ let Some(field_ident) = field.ident.as_ref() else {
+ unreachable!();
+ };
+
+ let field_var_ident = format_ident!("field_{field_ident}");
+
+ quote! {
+ #field_ident: *#field_var_ident
+ }
+ });
+
+ quote! {
+ Self::#variant_ident {
+ #(#fields),*
+ }
+ }
+ }
+ syn::Fields::Unnamed(unnamed_fields) => {
+ let variant_ident = &variant.ident;
+
+ let fields = unnamed_fields.unnamed.iter().enumerate().map(
+ |(field_index, _)| {
+ let field_var_ident = format_ident!("field_{field_index}");
+
+ quote! {
+ *#field_var_ident
+ }
+ },
+ );
+
+ quote! {
+ Self::#variant_ident(
+ #(#fields),*
+ )
+ }
+ }
+ };
+
quote! {
#engine_crate_path::reflection::EnumVariant {
name: #variant_name,
fields: #fields,
discriminant: #engine_crate_path::reflection::EnumDiscriminant {
buf: { #discriminant }
+ },
+ try_write_new_to: |dst, fields| {
+ use std::any::Any;
+ use #engine_crate_path::reflection::EnumVariantWriteNewToError;
+
+ let dst = dst
+ .downcast_mut()
+ .ok_or(EnumVariantWriteNewToError::WrongDstType)?;
+
+ #(#variant_field_vars)*;
+
+ let created = #variant_construction;
+
+ if fields.next().is_some() {
+ return Err(EnumVariantWriteNewToError::TooManyFields);
+ }
+
+ *dst = created;
+
+ Ok(())
}
}
}