From 99f2ac4794518d9a18e1acca131c66932b56882a Mon Sep 17 00:00:00 2001 From: Gino Valente <49806985+MrGVSV@users.noreply.github.com> Date: Sat, 3 Feb 2024 18:32:48 -0700 Subject: [PATCH] bevy_reflect: Reflect `&'static str` (#11686) # Objective `&'static str` doesn't implement `Reflect`. I don't think this was intentionally excluded. ## Solution Make `&'static str` implement `Reflect`. --- ## Changelog - Implement `Reflect` and friends for `&'static str` - Add missing `Reflect::debug` implementation for `Cow<'static, str>` --- crates/bevy_reflect/src/impls/std.rs | 113 +++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 3d522e94621557..61ae6db26bc77a 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -1111,6 +1111,10 @@ impl Reflect for Cow<'static, str> { Some(false) } } + + fn debug(&self, f: &mut fmt::Formatter<'_>) -> core::fmt::Result { + fmt::Debug::fmt(self, f) + } } impl Typed for Cow<'static, str> { @@ -1305,6 +1309,108 @@ impl FromReflect for Cow<'static, [T]> { } } +impl Reflect for &'static str { + fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { + Some(::type_info()) + } + + fn into_any(self: Box) -> Box { + self + } + + fn as_any(&self) -> &dyn Any { + self + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } + + fn into_reflect(self: Box) -> Box { + self + } + + fn as_reflect(&self) -> &dyn Reflect { + self + } + + fn as_reflect_mut(&mut self) -> &mut dyn Reflect { + self + } + + fn apply(&mut self, value: &dyn Reflect) { + let value = value.as_any(); + if let Some(&value) = value.downcast_ref::() { + *self = value; + } else { + panic!("Value is not a {}.", Self::type_path()); + } + } + + fn set(&mut self, value: Box) -> Result<(), Box> { + *self = value.take()?; + Ok(()) + } + + fn reflect_ref(&self) -> ReflectRef { + ReflectRef::Value(self) + } + + fn reflect_mut(&mut self) -> ReflectMut { + ReflectMut::Value(self) + } + + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::Value(self) + } + + fn clone_value(&self) -> Box { + Box::new(*self) + } + + fn reflect_hash(&self) -> Option { + let mut hasher = reflect_hasher(); + Hash::hash(&std::any::Any::type_id(self), &mut hasher); + Hash::hash(self, &mut hasher); + Some(hasher.finish()) + } + + fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option { + let value = value.as_any(); + if let Some(value) = value.downcast_ref::() { + Some(std::cmp::PartialEq::eq(self, value)) + } else { + Some(false) + } + } + + fn debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self, f) + } +} + +impl Typed for &'static str { + fn type_info() -> &'static TypeInfo { + static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); + CELL.get_or_set(|| TypeInfo::Value(ValueInfo::new::())) + } +} + +impl GetTypeRegistration for &'static str { + fn get_type_registration() -> TypeRegistration { + let mut registration = TypeRegistration::of::(); + registration.insert::(FromType::::from_type()); + registration.insert::(FromType::::from_type()); + registration + } +} + +impl FromReflect for &'static str { + fn from_reflect(reflect: &dyn crate::Reflect) -> Option { + reflect.as_any().downcast_ref::().copied() + } +} + impl Reflect for &'static Path { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) @@ -1735,4 +1841,11 @@ mod tests { let output = <&'static Path as FromReflect>::from_reflect(&path).unwrap(); assert_eq!(path, output); } + + #[test] + fn static_str_should_from_reflect() { + let expected = "Hello, World!"; + let output = <&'static str as FromReflect>::from_reflect(&expected).unwrap(); + assert_eq!(expected, output); + } }