diff options
Diffstat (limited to 'engine-reflection/src')
| -rw-r--r-- | engine-reflection/src/lib.rs | 94 |
1 files changed, 78 insertions, 16 deletions
diff --git a/engine-reflection/src/lib.rs b/engine-reflection/src/lib.rs index 79a7417..dedfee7 100644 --- a/engine-reflection/src/lib.rs +++ b/engine-reflection/src/lib.rs @@ -109,6 +109,10 @@ 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>, } impl Struct @@ -169,10 +173,11 @@ pub struct EnumVariant fields: &mut dyn Iterator<Item = Box<dyn Any>>, ) -> Result<(), EnumVariantWriteNewToError>, - pub try_get_field_mut: fn( - target: &mut dyn Any, - field_index: usize, - ) -> Result<&mut dyn Any, EnumVariantGetFieldError>, + 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>, } #[derive(Debug, thiserror::Error)] @@ -192,16 +197,16 @@ pub enum EnumVariantWriteNewToError } #[derive(Debug, thiserror::Error)] -pub enum EnumVariantGetFieldError +pub enum GetError { - #[error("Target is not the same type as the variant's enum")] + #[error("Target is not the correct type")] WrongTargetType, - #[error("Target is not the correct variant")] - WrongTargetVariant, + #[error("Target is not the correct enum variant")] + WrongTargetEnumVariant, - #[error("Field index is out of bounds")] - FieldIndexOutOfBounds, + #[error("Index is out of bounds")] + IndexOutOfBounds, } #[derive(Debug, Clone)] @@ -288,6 +293,9 @@ 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>, } impl Array @@ -304,6 +312,8 @@ pub struct Slice pub item_type: &'static Type, pub item_layout: Layout, pub get_item_type_name: FnWithDebug<&'static str>, + pub try_get_item: fn(target: &dyn Any, index: usize) -> Result<&dyn Any, GetError>, + pub try_get_len: fn(target: &dyn Any) -> Option<usize>, } impl Slice @@ -346,6 +356,7 @@ pub struct Reference { pub ty: &'static Type, pub cast_dyn_any: CastDynAnyFn, + pub try_deref: fn(target: &dyn Any) -> Option<&dyn Any>, } #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -432,6 +443,24 @@ 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>() + .ok_or(GetError::WrongTargetType)?; + + let item = target.get_mut(index).ok_or(GetError::IndexOutOfBounds)?; + + Ok(item) + }, }); } @@ -441,6 +470,20 @@ unsafe impl<T: Reflection> Reflection for &'static [T] item_type: T::TYPE_REFLECTION, item_layout: Layout::new::<T>(), get_item_type_name: FnWithDebug::new(|| type_name::<T>()), + 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_len: |target| { + let target = target.downcast_ref::<Self>()?; + + Some(target.len()) + }, }); } @@ -449,6 +492,11 @@ unsafe impl<T: Reflection> Reflection for &'static T const TYPE_REFLECTION: &Type = &Type::Reference(Reference { ty: T::TYPE_REFLECTION, cast_dyn_any: |ptr| ptr.cast::<Self>(), + try_deref: |target| { + let target = target.downcast_ref::<Self>()?; + + Some(*target) + }, }); } @@ -486,17 +534,32 @@ 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(EnumVariantGetFieldError::FieldIndexOutOfBounds); + return Err(GetError::IndexOutOfBounds); } let target = target .downcast_mut::<Self>() - .ok_or(EnumVariantGetFieldError::WrongTargetType)?; + .ok_or(GetError::WrongTargetType)?; let Some(value_field) = target else { - return Err(EnumVariantGetFieldError::WrongTargetVariant); + return Err(GetError::WrongTargetEnumVariant); }; Ok(value_field) @@ -518,9 +581,8 @@ unsafe impl<T: Reflection> Reflection for Option<T> Ok(()) }, - try_get_field_mut: |_, _| { - Err(EnumVariantGetFieldError::FieldIndexOutOfBounds) - }, + try_get_field: |_, _| Err(GetError::IndexOutOfBounds), + try_get_field_mut: |_, _| Err(GetError::IndexOutOfBounds), }, ], is_unit_only: false, |
