summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-07-05 02:02:53 +0200
committerHampusM <hampus@hampusmat.com>2026-07-05 02:02:53 +0200
commit237107c971707d297c1f2d3e536ca52289ae4206 (patch)
tree4278ebfb6e4bdd7ac65ef26f539bc8a5ef353cfa
parent377367bc67a9eac69951562aea1cdc5040e20b80 (diff)
feat(engine-reflection): add Reflection impl for Option<T>
-rw-r--r--engine-reflection/src/lib.rs77
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>
{