summaryrefslogtreecommitdiff
path: root/engine-macros/src
diff options
context:
space:
mode:
Diffstat (limited to 'engine-macros/src')
-rw-r--r--engine-macros/src/reflection/enum_impl.rs55
1 files changed, 47 insertions, 8 deletions
diff --git a/engine-macros/src/reflection/enum_impl.rs b/engine-macros/src/reflection/enum_impl.rs
index e4743b6..7f7d25e 100644
--- a/engine-macros/src/reflection/enum_impl.rs
+++ b/engine-macros/src/reflection/enum_impl.rs
@@ -73,16 +73,13 @@ pub fn generate(input: syn::ItemEnum) -> proc_macro2::TokenStream
.unwrap();
}
+ if !has_c_repr && primitive_repr.is_none() {
+ panic!("Enums must have a C or primitive representation to derive Reflection");
+ }
+
let mod_content = if is_unit_only {
quote! {}
} else {
- if !has_c_repr && primitive_repr.is_none() {
- panic!(concat!(
- "Non unit-only enums must have a C or ",
- "primitive representation to derive Reflection"
- ));
- }
-
let variant_fields_structs = input.variants.iter().map(|variant| {
let fields = variant.fields.iter().map(|field| {
let field_type = &field.ty;
@@ -314,10 +311,52 @@ fn generate_variants<'a>(
}
};
+ let enum_ident = &input.ident;
+
+ let discriminant = match variant.fields {
+ syn::Fields::Unit => {
+ quote! {
+ let mut buf = [0u8; std::mem::size_of::<i128>()];
+
+ let discriminant = #enum_ident::#variant_ident;
+
+ unsafe {
+ std::ptr::copy_nonoverlapping(
+ (&raw const discriminant).cast::<u8>(),
+ buf.as_mut_ptr(),
+ std::mem::size_of::<#enum_ident>(),
+ );
+ }
+
+ buf
+ }
+ }
+ _ => {
+ quote! {
+ let mut buf = [0u8; std::mem::size_of::<i128>()];
+
+ let discriminant = #mod_name::Discriminant::#variant_ident;
+
+ unsafe {
+ std::ptr::copy_nonoverlapping(
+ (&raw const discriminant).cast::<u8>(),
+ buf.as_mut_ptr(),
+ std::mem::size_of::<#mod_name::Discriminant>(),
+ );
+ }
+
+ buf
+ }
+ }
+ };
+
quote! {
#engine_crate_path::reflection::EnumVariant {
name: #variant_name,
- fields: #fields
+ fields: #fields,
+ discriminant: #engine_crate_path::reflection::EnumDiscriminant {
+ buf: { #discriminant }
+ }
}
}
})