From 62fe748a90efc35e9a5839b55b75a3db043102f1 Mon Sep 17 00:00:00 2001 From: HampusM Date: Tue, 9 Jun 2026 00:13:13 +0200 Subject: refactor(engine-macros): split up into multiple modules --- engine-macros/src/reflection/enum_impl.rs | 125 ++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 engine-macros/src/reflection/enum_impl.rs (limited to 'engine-macros/src/reflection/enum_impl.rs') diff --git a/engine-macros/src/reflection/enum_impl.rs b/engine-macros/src/reflection/enum_impl.rs new file mode 100644 index 0000000..0d9ff8b --- /dev/null +++ b/engine-macros/src/reflection/enum_impl.rs @@ -0,0 +1,125 @@ +use quote::quote; + +use crate::reflection::field::{generate as generate_field, ReflectionFieldGenOptions}; +use crate::util::find_engine_crate_path; + +pub fn generate(input: syn::ItemEnum) -> proc_macro2::TokenStream +{ + let engine_crate_path = find_engine_crate_path().unwrap(); + + let input_ident = input.ident; + + let (impl_generics, type_generics, where_clause) = input.generics.split_for_impl(); + + let variants = input.variants.iter().map(|variant| { + let variant_name = + syn::LitStr::new(&variant.ident.to_string(), variant.ident.span()); + + let fields = match &variant.fields { + syn::Fields::Unit => quote! { None }, + syn::Fields::Named(named_fields) => { + let fields = named_fields.named.iter().enumerate().map( + |(variant_field_index, variant_field)| { + generate_field( + variant_field, + variant_field_index, + &engine_crate_path, + ReflectionFieldGenOptions { + field_vis_override: None, + include_byte_offset: false, + }, + ) + }, + ); + + quote! { + Some(#engine_crate_path::reflection::EnumVariantFields::Named { + fields: &[#(#fields),*] + }) + } + } + syn::Fields::Unnamed(unnamed_fields) => { + let fields = unnamed_fields.unnamed.iter().enumerate().map( + |(variant_field_index, variant_field)| { + generate_field( + variant_field, + variant_field_index, + &engine_crate_path, + ReflectionFieldGenOptions { + field_vis_override: None, + include_byte_offset: false, + }, + ) + }, + ); + + quote! { + Some(#engine_crate_path::reflection::EnumVariantFields::Unnamed { + fields: &[#(#fields),*] + }) + } + } + }; + + quote! { + #engine_crate_path::reflection::EnumVariant { + name: #variant_name, + fields: #fields + } + } + }); + + let variant_lookup_match_arms = + input.variants.iter().enumerate().map(|(index, variant)| { + let variant_ident = &variant.ident; + + let pattern = match variant.fields { + syn::Fields::Unit => quote! { Self::#variant_ident }, + syn::Fields::Named(_) => quote! { Self::#variant_ident { .. } }, + syn::Fields::Unnamed(_) => quote! { Self::#variant_ident(..) }, + }; + + quote! { + #pattern => &enum_reflection.variants[#index] + } + }); + + let is_unit_only = input + .variants + .iter() + .all(|variant| matches!(variant.fields, syn::Fields::Unit)); + + quote! { + unsafe impl #impl_generics #engine_crate_path::reflection::Reflection for + #input_ident #type_generics #where_clause + { + const TYPE_REFLECTION: &#engine_crate_path::reflection::Type = + &const { + #engine_crate_path::reflection::Type::Enum( + #engine_crate_path::reflection::Enum { + variants: &[#(#variants),*], + is_unit_only: #is_unit_only + } + ) + }; + } + + unsafe impl #impl_generics #engine_crate_path::reflection::EnumReflectionExt for + #input_ident #type_generics #where_clause + { + fn get_variant_reflection(&self) + -> &'static #engine_crate_path::reflection::EnumVariant + { + let enum_reflection = unsafe { + ::TYPE_REFLECTION + .as_enum() + .unwrap_unchecked() + }; + + match self { + #(#variant_lookup_match_arms),* + } + } + } + } +} -- cgit v1.2.3-18-g5258