diff options
| author | HampusM <hampus@hampusmat.com> | 2026-07-17 00:31:02 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-07-17 00:31:02 +0200 |
| commit | a4a30c4b53221fa3bbad5a3c998810b9709c106a (patch) | |
| tree | a05de329855f934caa62be2667b6d6ea52a7b3cd | |
| parent | ee5daec60b373210cb5b8de93959394b4b605382 (diff) | |
feat(engine): add immutable try_get* fns to reflection
| -rw-r--r-- | engine-macros/src/reflection/enum_impl.rs | 23 | ||||
| -rw-r--r-- | engine-macros/src/reflection/struct_impl.rs | 18 | ||||
| -rw-r--r-- | engine-reflection/src/lib.rs | 31 |
3 files changed, 72 insertions, 0 deletions
diff --git a/engine-macros/src/reflection/enum_impl.rs b/engine-macros/src/reflection/enum_impl.rs index 37abc34..14d91a7 100644 --- a/engine-macros/src/reflection/enum_impl.rs +++ b/engine-macros/src/reflection/enum_impl.rs @@ -352,6 +352,29 @@ fn generate_variants<'a>( Ok(()) }, + try_get_field: |target, field_index| { { + #![allow(unreachable_code)] + + use std::any::Any; + use #engine_crate_path::reflection::GetError; + + let target = target + .downcast_ref::<Self>() + .ok_or(GetError::WrongTargetType)?; + + let #variant_pattern = target else { + return Err(GetError::WrongTargetEnumVariant); + }; + + let field: &dyn Any = match field_index { + #field_index_match_arms + _ => { + return Err(GetError::IndexOutOfBounds); + } + }; + + Ok(field) + } }, try_get_field_mut: |target, field_index| { { #![allow(unreachable_code)] diff --git a/engine-macros/src/reflection/struct_impl.rs b/engine-macros/src/reflection/struct_impl.rs index 1cd9fb8..0ba426d 100644 --- a/engine-macros/src/reflection/struct_impl.rs +++ b/engine-macros/src/reflection/struct_impl.rs @@ -142,6 +142,24 @@ fn gen_impl( #get_default_value_fn }, cast_dyn_any: |ptr| ptr.cast::<Self>(), + try_get_field: |target, field_index| { { + #![allow(unreachable_code)] + + let target = target + .downcast_ref::<Self>() + .ok_or(GetError::WrongTargetType)?; + + let #struct_pattern = target; + + let field: &dyn Any = match field_index { + #field_index_match_arms + _ => { + return Err(GetError::IndexOutOfBounds); + } + }; + + Ok(field) + } }, try_get_field_mut: |target, field_index| { { #![allow(unreachable_code)] diff --git a/engine-reflection/src/lib.rs b/engine-reflection/src/lib.rs index 4ef688c..d9e2c72 100644 --- a/engine-reflection/src/lib.rs +++ b/engine-reflection/src/lib.rs @@ -109,6 +109,8 @@ pub struct Struct pub fields: &'static [Field], pub get_default_value: fn() -> Option<DefaultValueFn>, pub cast_dyn_any: CastDynAnyFn, + pub try_get_field: + fn(target: &dyn Any, field_index: usize) -> Result<&dyn Any, GetError>, pub try_get_field_mut: fn(target: &mut dyn Any, field_index: usize) -> Result<&mut dyn Any, GetError>, } @@ -171,6 +173,9 @@ pub struct EnumVariant fields: &mut dyn Iterator<Item = Box<dyn Any>>, ) -> Result<(), EnumVariantWriteNewToError>, + pub try_get_field: + fn(target: &dyn Any, field_index: usize) -> Result<&dyn Any, GetError>, + pub try_get_field_mut: fn(target: &mut dyn Any, field_index: usize) -> Result<&mut dyn Any, GetError>, } @@ -288,6 +293,7 @@ pub struct Array pub get_item_type_name: FnWithDebug<&'static str>, pub length: usize, pub cast_dyn_any: CastDynAnyFn, + pub try_get_item: fn(target: &dyn Any, index: usize) -> Result<&dyn Any, GetError>, pub try_get_item_mut: fn(target: &mut dyn Any, index: usize) -> Result<&mut dyn Any, GetError>, } @@ -435,6 +441,15 @@ unsafe impl<T: Reflection, const LEN: usize> Reflection for [T; LEN] get_item_type_name: FnWithDebug::new(|| type_name::<T>()), length: LEN, cast_dyn_any: |ptr| ptr.cast::<Self>(), + try_get_item: |target, index| { + let target = target + .downcast_ref::<Self>() + .ok_or(GetError::WrongTargetType)?; + + let item = target.get(index).ok_or(GetError::IndexOutOfBounds)?; + + Ok(item) + }, try_get_item_mut: |target, index| { let target = target .downcast_mut::<Self>() @@ -507,6 +522,21 @@ unsafe impl<T: Reflection> Reflection for Option<T> Ok(()) }, + try_get_field: |target, field_index| { + if field_index != 0 { + return Err(GetError::IndexOutOfBounds); + } + + let target = target + .downcast_ref::<Self>() + .ok_or(GetError::WrongTargetType)?; + + let Some(value_field) = target else { + return Err(GetError::WrongTargetEnumVariant); + }; + + Ok(value_field) + }, try_get_field_mut: |target, field_index| { if field_index != 0 { return Err(GetError::IndexOutOfBounds); @@ -539,6 +569,7 @@ unsafe impl<T: Reflection> Reflection for Option<T> Ok(()) }, + try_get_field: |_, _| Err(GetError::IndexOutOfBounds), try_get_field_mut: |_, _| Err(GetError::IndexOutOfBounds), }, ], |
