From 217040cca5cea1d5f69c6a2da4ec4a7c6f9b5c73 Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Fri, 25 Nov 2022 23:49:26 +0000 Subject: [PATCH] impl `Reflect` for `&'static Path` (#6755) # Objective Fixes #6739 ## Solution Implement the required traits. They cannot be implemented for `Path` directly, since it is a dynamically-sized type. --- crates/bevy_reflect/src/impls/std.rs | 110 +++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index ce56cef43f2196..4f72bdb2f3a62a 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -14,6 +14,7 @@ use bevy_utils::{Duration, Instant}; use bevy_utils::{HashMap, HashSet}; #[cfg(any(unix, windows))] use std::ffi::OsString; +use std::path::Path; use std::{ any::Any, borrow::Cow, @@ -745,6 +746,86 @@ impl Reflect for Cow<'static, str> { } } +impl Reflect for &'static Path { + fn type_name(&self) -> &str { + std::any::type_name::() + } + + fn get_type_info(&self) -> &'static TypeInfo { + ::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 {}.", std::any::type_name::()); + } + } + + 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 = crate::ReflectHasher::default(); + 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) + } + } +} + impl GetTypeRegistration for Option { fn get_type_registration() -> TypeRegistration { TypeRegistration::of::>() @@ -1019,6 +1100,27 @@ impl FromReflect for Cow<'static, str> { } } +impl Typed for &'static Path { + fn type_info() -> &'static TypeInfo { + static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); + CELL.get_or_set(|| TypeInfo::Value(ValueInfo::new::())) + } +} + +impl GetTypeRegistration for &'static Path { + fn get_type_registration() -> TypeRegistration { + let mut registration = TypeRegistration::of::(); + registration.insert::(FromType::::from_type()); + registration + } +} + +impl FromReflect for &'static Path { + fn from_reflect(reflect: &dyn crate::Reflect) -> Option { + reflect.as_any().downcast_ref::().copied() + } +} + #[cfg(test)] mod tests { use crate as bevy_reflect; @@ -1029,6 +1131,7 @@ mod tests { use bevy_utils::HashMap; use bevy_utils::{Duration, Instant}; use std::f32::consts::{PI, TAU}; + use std::path::Path; #[test] fn can_serialize_duration() { @@ -1228,4 +1331,11 @@ mod tests { let output = ::from_reflect(&expected).unwrap(); assert_eq!(expected, output); } + + #[test] + fn path_should_from_reflect() { + let path = Path::new("hello_world.rs"); + let output = <&'static Path as FromReflect>::from_reflect(&path).unwrap(); + assert_eq!(path, output); + } }