Skip to main content

bevy_reflect/impls/alloc/
borrow.rs

1use crate::{
2    error::ReflectCloneError,
3    kind::{ReflectKind, ReflectMut, ReflectOwned, ReflectRef},
4    list::{List, ListInfo, ListIter},
5    prelude::*,
6    reflect::{impl_full_reflect, ApplyError},
7    type_info::{MaybeTyped, OpaqueInfo, TypeInfo, Typed},
8    type_registry::{
9        FromType, GetTypeRegistration, ReflectDeserialize, ReflectFromPtr, ReflectSerialize,
10        TypeRegistration, TypeRegistry,
11    },
12    utility::{reflect_hasher, GenericTypeInfoCell, NonGenericTypeInfoCell},
13};
14use alloc::borrow::Cow;
15use alloc::vec::Vec;
16use bevy_platform::prelude::*;
17use bevy_reflect_derive::impl_type_path;
18use core::any::Any;
19use core::fmt;
20use core::hash::{Hash, Hasher};
21
22impl_type_path!(::alloc::borrow::Cow<'a: 'static, T: ToOwned + ?Sized>);
23
24impl PartialReflect for Cow<'static, str> {
25    fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
26        Some(<Self as Typed>::type_info())
27    }
28
29    #[inline]
30    fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
31        self
32    }
33
34    fn as_partial_reflect(&self) -> &dyn PartialReflect {
35        self
36    }
37
38    fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
39        self
40    }
41
42    fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
43        Ok(self)
44    }
45
46    fn try_as_reflect(&self) -> Option<&dyn Reflect> {
47        Some(self)
48    }
49
50    fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
51        Some(self)
52    }
53
54    fn reflect_kind(&self) -> ReflectKind {
55        ReflectKind::Opaque
56    }
57
58    fn reflect_ref(&self) -> ReflectRef<'_> {
59        ReflectRef::Opaque(self)
60    }
61
62    fn reflect_mut(&mut self) -> ReflectMut<'_> {
63        ReflectMut::Opaque(self)
64    }
65
66    fn reflect_owned(self: Box<Self>) -> ReflectOwned {
67        ReflectOwned::Opaque(self)
68    }
69
70    fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError> {
71        Ok(Box::new(self.clone()))
72    }
73
74    fn reflect_hash(&self) -> Option<u64> {
75        let mut hasher = reflect_hasher();
76        Hash::hash(&Any::type_id(self), &mut hasher);
77        Hash::hash(self, &mut hasher);
78        Some(hasher.finish())
79    }
80
81    fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option<bool> {
82        if let Some(value) = value.try_downcast_ref::<Self>() {
83            Some(PartialEq::eq(self, value))
84        } else {
85            Some(false)
86        }
87    }
88
89    fn reflect_partial_cmp(&self, value: &dyn PartialReflect) -> Option<core::cmp::Ordering> {
90        if let Some(value) = value.try_downcast_ref::<Self>() {
91            PartialOrd::partial_cmp(self, value)
92        } else {
93            None
94        }
95    }
96
97    fn debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98        fmt::Debug::fmt(self, f)
99    }
100
101    fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> {
102        if let Some(value) = value.try_downcast_ref::<Self>() {
103            self.clone_from(value);
104        } else {
105            return Err(ApplyError::MismatchedTypes {
106                from_type: value.reflect_type_path().into(),
107                // If we invoke the reflect_type_path on self directly the borrow checker complains that the lifetime of self must outlive 'static
108                to_type: Self::type_path().into(),
109            });
110        }
111        Ok(())
112    }
113}
114
115impl_full_reflect!(for Cow<'static, str>);
116
117impl Typed for Cow<'static, str> {
118    fn type_info() -> &'static TypeInfo {
119        static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
120        CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
121    }
122}
123
124impl GetTypeRegistration for Cow<'static, str> {
125    fn get_type_registration() -> TypeRegistration {
126        let mut registration = TypeRegistration::of::<Cow<'static, str>>();
127        registration.insert::<ReflectDeserialize>(FromType::<Cow<'static, str>>::from_type());
128        registration.insert::<ReflectFromPtr>(FromType::<Cow<'static, str>>::from_type());
129        registration.insert::<ReflectFromReflect>(FromType::<Cow<'static, str>>::from_type());
130        registration.insert::<ReflectSerialize>(FromType::<Cow<'static, str>>::from_type());
131        registration
132    }
133}
134
135impl FromReflect for Cow<'static, str> {
136    fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
137        Some(reflect.try_downcast_ref::<Cow<'static, str>>()?.clone())
138    }
139}
140
141#[cfg(feature = "functions")]
142crate::func::macros::impl_function_traits!(Cow<'static, str>);
143
144impl<T: FromReflect + MaybeTyped + Clone + TypePath + GetTypeRegistration> List
145    for Cow<'static, [T]>
146{
147    fn get(&self, index: usize) -> Option<&dyn PartialReflect> {
148        self.as_ref().get(index).map(|x| x as &dyn PartialReflect)
149    }
150
151    fn get_mut(&mut self, index: usize) -> Option<&mut dyn PartialReflect> {
152        self.to_mut()
153            .get_mut(index)
154            .map(|x| x as &mut dyn PartialReflect)
155    }
156
157    fn insert(&mut self, index: usize, element: Box<dyn PartialReflect>) {
158        let value = T::take_from_reflect(element).unwrap_or_else(|value| {
159            panic!(
160                "Attempted to insert invalid value of type {}.",
161                value.reflect_type_path()
162            );
163        });
164        self.to_mut().insert(index, value);
165    }
166
167    fn remove(&mut self, index: usize) -> Box<dyn PartialReflect> {
168        Box::new(self.to_mut().remove(index))
169    }
170
171    fn push(&mut self, value: Box<dyn PartialReflect>) {
172        let value = T::take_from_reflect(value).unwrap_or_else(|value| {
173            panic!(
174                "Attempted to push invalid value of type {}.",
175                value.reflect_type_path()
176            )
177        });
178        self.to_mut().push(value);
179    }
180
181    fn pop(&mut self) -> Option<Box<dyn PartialReflect>> {
182        self.to_mut()
183            .pop()
184            .map(|value| Box::new(value) as Box<dyn PartialReflect>)
185    }
186
187    fn len(&self) -> usize {
188        self.as_ref().len()
189    }
190
191    fn iter(&self) -> ListIter<'_> {
192        ListIter::new(self)
193    }
194
195    fn drain(&mut self) -> Vec<Box<dyn PartialReflect>> {
196        self.to_mut()
197            .drain(..)
198            .map(|value| Box::new(value) as Box<dyn PartialReflect>)
199            .collect()
200    }
201}
202
203impl<T: FromReflect + MaybeTyped + Clone + TypePath + GetTypeRegistration> PartialReflect
204    for Cow<'static, [T]>
205{
206    fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
207        Some(<Self as Typed>::type_info())
208    }
209
210    #[inline]
211    fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
212        self
213    }
214
215    fn as_partial_reflect(&self) -> &dyn PartialReflect {
216        self
217    }
218
219    fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
220        self
221    }
222
223    fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
224        Ok(self)
225    }
226
227    fn try_as_reflect(&self) -> Option<&dyn Reflect> {
228        Some(self)
229    }
230
231    fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
232        Some(self)
233    }
234
235    fn reflect_kind(&self) -> ReflectKind {
236        ReflectKind::List
237    }
238
239    fn reflect_ref(&self) -> ReflectRef<'_> {
240        ReflectRef::List(self)
241    }
242
243    fn reflect_mut(&mut self) -> ReflectMut<'_> {
244        ReflectMut::List(self)
245    }
246
247    fn reflect_owned(self: Box<Self>) -> ReflectOwned {
248        ReflectOwned::List(self)
249    }
250
251    fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError> {
252        Ok(Box::new(self.clone()))
253    }
254
255    fn reflect_hash(&self) -> Option<u64> {
256        crate::list::list_hash(self)
257    }
258
259    fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option<bool> {
260        crate::list::list_partial_eq(self, value)
261    }
262
263    fn reflect_partial_cmp(&self, value: &dyn PartialReflect) -> Option<::core::cmp::Ordering> {
264        crate::list::list_partial_cmp(self, value)
265    }
266
267    fn apply(&mut self, value: &dyn PartialReflect) {
268        crate::list::list_apply(self, value);
269    }
270
271    fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> {
272        crate::list::list_try_apply(self, value)
273    }
274}
275
276impl_full_reflect!(
277    <T> for Cow<'static, [T]>
278    where
279        T: FromReflect + Clone + MaybeTyped + TypePath + GetTypeRegistration,
280);
281
282impl<T: FromReflect + MaybeTyped + Clone + TypePath + GetTypeRegistration> Typed
283    for Cow<'static, [T]>
284{
285    fn type_info() -> &'static TypeInfo {
286        static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new();
287        CELL.get_or_insert::<Self, _>(|| TypeInfo::List(ListInfo::new::<Self, T>()))
288    }
289}
290
291impl<T: FromReflect + MaybeTyped + Clone + TypePath + GetTypeRegistration> GetTypeRegistration
292    for Cow<'static, [T]>
293{
294    fn get_type_registration() -> TypeRegistration {
295        TypeRegistration::of::<Cow<'static, [T]>>()
296    }
297
298    fn register_type_dependencies(registry: &mut TypeRegistry) {
299        registry.register::<T>();
300    }
301}
302
303impl<T: FromReflect + MaybeTyped + Clone + TypePath + GetTypeRegistration> FromReflect
304    for Cow<'static, [T]>
305{
306    fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
307        let ref_list = reflect.reflect_ref().as_list().ok()?;
308
309        let mut temp_vec = Vec::with_capacity(ref_list.len());
310
311        for field in ref_list.iter() {
312            temp_vec.push(T::from_reflect(field)?);
313        }
314
315        Some(temp_vec.into())
316    }
317}
318
319#[cfg(feature = "functions")]
320crate::func::macros::impl_function_traits!(Cow<'static, [T]>; <T: FromReflect + MaybeTyped + Clone + TypePath + GetTypeRegistration>);