diff options
| author | HampusM <hampus@hampusmat.com> | 2026-07-05 02:02:53 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-07-05 02:02:53 +0200 |
| commit | 237107c971707d297c1f2d3e536ca52289ae4206 (patch) | |
| tree | 4278ebfb6e4bdd7ac65ef26f539bc8a5ef353cfa | |
| parent | 377367bc67a9eac69951562aea1cdc5040e20b80 (diff) | |
feat(engine-reflection): add Reflection impl for Option<T>
| -rw-r--r-- | engine-reflection/src/lib.rs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/engine-reflection/src/lib.rs b/engine-reflection/src/lib.rs index 62fa4f5..8436e65 100644 --- a/engine-reflection/src/lib.rs +++ b/engine-reflection/src/lib.rs @@ -421,6 +421,83 @@ unsafe impl<T: Reflection> Reflection for &'static T }); } +unsafe impl<T: Reflection> Reflection for Option<T> +{ + const TYPE_REFLECTION: &Type = &Type::Enum(Enum { + variants: &[ + EnumVariant { + name: "Some", + fields: Some(EnumVariantFields::Unnamed { + fields: &[EnumVariantField { + name: None, + index: 0, + type_id: TypeId::of::<T>(), + get_type_name: FnWithDebug::new(|| type_name::<T>()), + get_type: FnWithDebug::new(|| Some(T::type_reflection())), + }], + }), + try_write_new_to: |dst, fields| { + let dst = dst + .downcast_mut::<Self>() + .ok_or(EnumVariantWriteNewToError::WrongDstType)?; + + let value_field = fields + .next() + .ok_or(EnumVariantWriteNewToError::TooFewFields)? + .downcast::<T>() + .map_err(|_| EnumVariantWriteNewToError::WrongFieldType)?; + + if fields.next().is_some() { + return Err(EnumVariantWriteNewToError::TooManyFields); + } + + *dst = Some(*value_field); + + Ok(()) + }, + }, + EnumVariant { + name: "None", + fields: None, + try_write_new_to: |dst, fields| { + let dst = dst + .downcast_mut::<Self>() + .ok_or(EnumVariantWriteNewToError::WrongDstType)?; + + if fields.next().is_some() { + return Err(EnumVariantWriteNewToError::TooManyFields); + } + + *dst = None; + + Ok(()) + }, + }, + ], + is_unit_only: false, + get_default_value: || Some(|| Box::new(Option::<T>::None)), + cast_dyn_any: |ptr| ptr.cast::<Self>(), + get_variant_reflection: |target| { + let target = target.downcast_ref::<Self>()?; + + Some(target.get_variant_reflection()) + }, + }); +} + +unsafe impl<T: Reflection> EnumReflectionExt for Option<T> +{ + fn get_variant_reflection(&self) -> &'static EnumVariant + { + let ty = unsafe { Self::type_reflection().as_enum().unwrap_unchecked() }; + + match self { + Some(_) => &ty.variants[0], + None => &ty.variants[1], + } + } +} + #[derive(Clone)] pub struct FnWithDebug<Value> { |
