bevy_reflect/impls/core/
primitives.rs

1use crate::{
2    array::{Array, ArrayInfo, ArrayIter},
3    error::ReflectCloneError,
4    kind::{ReflectKind, ReflectMut, ReflectOwned, ReflectRef},
5    prelude::*,
6    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, GenericTypePathCell, NonGenericTypeInfoCell},
13};
14use bevy_platform::prelude::*;
15use bevy_reflect_derive::{impl_reflect_opaque, impl_type_path};
16use core::any::Any;
17use core::fmt;
18use core::hash::{Hash, Hasher};
19
20impl_reflect_opaque!(bool(
21    Clone,
22    Debug,
23    Hash,
24    PartialEq,
25    Serialize,
26    Deserialize,
27    Default
28));
29impl_reflect_opaque!(char(
30    Clone,
31    Debug,
32    Hash,
33    PartialEq,
34    Serialize,
35    Deserialize,
36    Default
37));
38impl_reflect_opaque!(u8(
39    Clone,
40    Debug,
41    Hash,
42    PartialEq,
43    Serialize,
44    Deserialize,
45    Default
46));
47impl_reflect_opaque!(u16(
48    Clone,
49    Debug,
50    Hash,
51    PartialEq,
52    Serialize,
53    Deserialize,
54    Default
55));
56impl_reflect_opaque!(u32(
57    Clone,
58    Debug,
59    Hash,
60    PartialEq,
61    Serialize,
62    Deserialize,
63    Default
64));
65impl_reflect_opaque!(u64(
66    Clone,
67    Debug,
68    Hash,
69    PartialEq,
70    Serialize,
71    Deserialize,
72    Default
73));
74impl_reflect_opaque!(u128(
75    Clone,
76    Debug,
77    Hash,
78    PartialEq,
79    Serialize,
80    Deserialize,
81    Default
82));
83impl_reflect_opaque!(usize(
84    Clone,
85    Debug,
86    Hash,
87    PartialEq,
88    Serialize,
89    Deserialize,
90    Default
91));
92impl_reflect_opaque!(i8(
93    Clone,
94    Debug,
95    Hash,
96    PartialEq,
97    Serialize,
98    Deserialize,
99    Default
100));
101impl_reflect_opaque!(i16(
102    Clone,
103    Debug,
104    Hash,
105    PartialEq,
106    Serialize,
107    Deserialize,
108    Default
109));
110impl_reflect_opaque!(i32(
111    Clone,
112    Debug,
113    Hash,
114    PartialEq,
115    Serialize,
116    Deserialize,
117    Default
118));
119impl_reflect_opaque!(i64(
120    Clone,
121    Debug,
122    Hash,
123    PartialEq,
124    Serialize,
125    Deserialize,
126    Default
127));
128impl_reflect_opaque!(i128(
129    Clone,
130    Debug,
131    Hash,
132    PartialEq,
133    Serialize,
134    Deserialize,
135    Default
136));
137impl_reflect_opaque!(isize(
138    Clone,
139    Debug,
140    Hash,
141    PartialEq,
142    Serialize,
143    Deserialize,
144    Default
145));
146impl_reflect_opaque!(f32(
147    Clone,
148    Debug,
149    PartialEq,
150    Serialize,
151    Deserialize,
152    Default
153));
154impl_reflect_opaque!(f64(
155    Clone,
156    Debug,
157    PartialEq,
158    Serialize,
159    Deserialize,
160    Default
161));
162impl_type_path!(str);
163
164impl PartialReflect for &'static str {
165    fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
166        Some(<Self as Typed>::type_info())
167    }
168
169    #[inline]
170    fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
171        self
172    }
173
174    fn as_partial_reflect(&self) -> &dyn PartialReflect {
175        self
176    }
177
178    fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
179        self
180    }
181
182    fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
183        Ok(self)
184    }
185
186    fn try_as_reflect(&self) -> Option<&dyn Reflect> {
187        Some(self)
188    }
189
190    fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
191        Some(self)
192    }
193
194    fn reflect_ref(&self) -> ReflectRef<'_> {
195        ReflectRef::Opaque(self)
196    }
197
198    fn reflect_mut(&mut self) -> ReflectMut<'_> {
199        ReflectMut::Opaque(self)
200    }
201
202    fn reflect_owned(self: Box<Self>) -> ReflectOwned {
203        ReflectOwned::Opaque(self)
204    }
205
206    fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError> {
207        Ok(Box::new(*self))
208    }
209
210    fn reflect_hash(&self) -> Option<u64> {
211        let mut hasher = reflect_hasher();
212        Hash::hash(&Any::type_id(self), &mut hasher);
213        Hash::hash(self, &mut hasher);
214        Some(hasher.finish())
215    }
216
217    fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option<bool> {
218        if let Some(value) = value.try_downcast_ref::<Self>() {
219            Some(PartialEq::eq(self, value))
220        } else {
221            Some(false)
222        }
223    }
224
225    fn debug(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226        fmt::Debug::fmt(&self, f)
227    }
228
229    fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> {
230        if let Some(value) = value.try_downcast_ref::<Self>() {
231            self.clone_from(value);
232        } else {
233            return Err(ApplyError::MismatchedTypes {
234                from_type: value.reflect_type_path().into(),
235                to_type: Self::type_path().into(),
236            });
237        }
238        Ok(())
239    }
240}
241
242impl Reflect for &'static str {
243    fn into_any(self: Box<Self>) -> Box<dyn Any> {
244        self
245    }
246
247    fn as_any(&self) -> &dyn Any {
248        self
249    }
250
251    fn as_any_mut(&mut self) -> &mut dyn Any {
252        self
253    }
254
255    fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
256        self
257    }
258
259    fn as_reflect(&self) -> &dyn Reflect {
260        self
261    }
262
263    fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
264        self
265    }
266
267    fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
268        *self = value.take()?;
269        Ok(())
270    }
271}
272
273impl Typed for &'static str {
274    fn type_info() -> &'static TypeInfo {
275        static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
276        CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
277    }
278}
279
280impl GetTypeRegistration for &'static str {
281    fn get_type_registration() -> TypeRegistration {
282        let mut registration = TypeRegistration::of::<Self>();
283        registration.insert::<ReflectFromPtr>(FromType::<Self>::from_type());
284        registration.insert::<ReflectFromReflect>(FromType::<Self>::from_type());
285        registration.insert::<ReflectSerialize>(FromType::<Self>::from_type());
286        registration
287    }
288}
289
290impl FromReflect for &'static str {
291    fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
292        reflect.try_downcast_ref::<Self>().copied()
293    }
294}
295
296impl<T: Reflect + MaybeTyped + TypePath + GetTypeRegistration, const N: usize> Array for [T; N] {
297    #[inline]
298    fn get(&self, index: usize) -> Option<&dyn PartialReflect> {
299        <[T]>::get(self, index).map(|value| value as &dyn PartialReflect)
300    }
301
302    #[inline]
303    fn get_mut(&mut self, index: usize) -> Option<&mut dyn PartialReflect> {
304        <[T]>::get_mut(self, index).map(|value| value as &mut dyn PartialReflect)
305    }
306
307    #[inline]
308    fn len(&self) -> usize {
309        N
310    }
311
312    #[inline]
313    fn iter(&self) -> ArrayIter<'_> {
314        ArrayIter::new(self)
315    }
316
317    #[inline]
318    fn drain(self: Box<Self>) -> Vec<Box<dyn PartialReflect>> {
319        self.into_iter()
320            .map(|value| Box::new(value) as Box<dyn PartialReflect>)
321            .collect()
322    }
323}
324
325impl<T: Reflect + MaybeTyped + TypePath + GetTypeRegistration, const N: usize> PartialReflect
326    for [T; N]
327{
328    fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
329        Some(<Self as Typed>::type_info())
330    }
331
332    #[inline]
333    fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
334        self
335    }
336
337    fn as_partial_reflect(&self) -> &dyn PartialReflect {
338        self
339    }
340
341    fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
342        self
343    }
344
345    fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
346        Ok(self)
347    }
348
349    fn try_as_reflect(&self) -> Option<&dyn Reflect> {
350        Some(self)
351    }
352
353    fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
354        Some(self)
355    }
356
357    #[inline]
358    fn reflect_kind(&self) -> ReflectKind {
359        ReflectKind::Array
360    }
361
362    #[inline]
363    fn reflect_ref(&self) -> ReflectRef<'_> {
364        ReflectRef::Array(self)
365    }
366
367    #[inline]
368    fn reflect_mut(&mut self) -> ReflectMut<'_> {
369        ReflectMut::Array(self)
370    }
371
372    #[inline]
373    fn reflect_owned(self: Box<Self>) -> ReflectOwned {
374        ReflectOwned::Array(self)
375    }
376
377    #[inline]
378    fn reflect_hash(&self) -> Option<u64> {
379        crate::array_hash(self)
380    }
381
382    #[inline]
383    fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option<bool> {
384        crate::array_partial_eq(self, value)
385    }
386
387    fn apply(&mut self, value: &dyn PartialReflect) {
388        crate::array_apply(self, value);
389    }
390
391    #[inline]
392    fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> {
393        crate::array_try_apply(self, value)
394    }
395}
396
397impl<T: Reflect + MaybeTyped + TypePath + GetTypeRegistration, const N: usize> Reflect for [T; N] {
398    #[inline]
399    fn into_any(self: Box<Self>) -> Box<dyn Any> {
400        self
401    }
402
403    #[inline]
404    fn as_any(&self) -> &dyn Any {
405        self
406    }
407
408    #[inline]
409    fn as_any_mut(&mut self) -> &mut dyn Any {
410        self
411    }
412
413    #[inline]
414    fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
415        self
416    }
417
418    #[inline]
419    fn as_reflect(&self) -> &dyn Reflect {
420        self
421    }
422
423    #[inline]
424    fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
425        self
426    }
427
428    #[inline]
429    fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
430        *self = value.take()?;
431        Ok(())
432    }
433}
434
435impl<T: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, const N: usize> FromReflect
436    for [T; N]
437{
438    fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
439        let ref_array = reflect.reflect_ref().as_array().ok()?;
440
441        let mut temp_vec = Vec::with_capacity(ref_array.len());
442
443        for field in ref_array.iter() {
444            temp_vec.push(T::from_reflect(field)?);
445        }
446
447        temp_vec.try_into().ok()
448    }
449}
450
451impl<T: Reflect + MaybeTyped + TypePath + GetTypeRegistration, const N: usize> Typed for [T; N] {
452    fn type_info() -> &'static TypeInfo {
453        static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new();
454        CELL.get_or_insert::<Self, _>(|| TypeInfo::Array(ArrayInfo::new::<Self, T>(N)))
455    }
456}
457
458impl<T: TypePath, const N: usize> TypePath for [T; N] {
459    fn type_path() -> &'static str {
460        static CELL: GenericTypePathCell = GenericTypePathCell::new();
461        CELL.get_or_insert::<Self, _>(|| format!("[{t}; {N}]", t = T::type_path()))
462    }
463
464    fn short_type_path() -> &'static str {
465        static CELL: GenericTypePathCell = GenericTypePathCell::new();
466        CELL.get_or_insert::<Self, _>(|| format!("[{t}; {N}]", t = T::short_type_path()))
467    }
468}
469
470impl<T: Reflect + MaybeTyped + TypePath + GetTypeRegistration, const N: usize> GetTypeRegistration
471    for [T; N]
472{
473    fn get_type_registration() -> TypeRegistration {
474        TypeRegistration::of::<[T; N]>()
475    }
476
477    fn register_type_dependencies(registry: &mut TypeRegistry) {
478        registry.register::<T>();
479    }
480}
481
482#[cfg(feature = "functions")]
483crate::func::macros::impl_function_traits!([T; N]; <T: Reflect + MaybeTyped + TypePath + GetTypeRegistration> [const N: usize]);
484
485impl<T: TypePath> TypePath for [T]
486where
487    [T]: ToOwned,
488{
489    fn type_path() -> &'static str {
490        static CELL: GenericTypePathCell = GenericTypePathCell::new();
491        CELL.get_or_insert::<Self, _>(|| format!("[{}]", <T>::type_path()))
492    }
493
494    fn short_type_path() -> &'static str {
495        static CELL: GenericTypePathCell = GenericTypePathCell::new();
496        CELL.get_or_insert::<Self, _>(|| format!("[{}]", <T>::short_type_path()))
497    }
498}
499
500impl<T: TypePath + ?Sized> TypePath for &'static T {
501    fn type_path() -> &'static str {
502        static CELL: GenericTypePathCell = GenericTypePathCell::new();
503        CELL.get_or_insert::<Self, _>(|| format!("&{}", T::type_path()))
504    }
505
506    fn short_type_path() -> &'static str {
507        static CELL: GenericTypePathCell = GenericTypePathCell::new();
508        CELL.get_or_insert::<Self, _>(|| format!("&{}", T::short_type_path()))
509    }
510}
511
512impl<T: TypePath + ?Sized> TypePath for &'static mut T {
513    fn type_path() -> &'static str {
514        static CELL: GenericTypePathCell = GenericTypePathCell::new();
515        CELL.get_or_insert::<Self, _>(|| format!("&mut {}", T::type_path()))
516    }
517
518    fn short_type_path() -> &'static str {
519        static CELL: GenericTypePathCell = GenericTypePathCell::new();
520        CELL.get_or_insert::<Self, _>(|| format!("&mut {}", T::short_type_path()))
521    }
522}
523
524#[cfg(test)]
525mod tests {
526    use bevy_reflect::{FromReflect, PartialReflect};
527    use core::f32::consts::{PI, TAU};
528
529    #[test]
530    fn should_partial_eq_char() {
531        let a: &dyn PartialReflect = &'x';
532        let b: &dyn PartialReflect = &'x';
533        let c: &dyn PartialReflect = &'o';
534        assert!(a.reflect_partial_eq(b).unwrap_or_default());
535        assert!(!a.reflect_partial_eq(c).unwrap_or_default());
536    }
537
538    #[test]
539    fn should_partial_eq_i32() {
540        let a: &dyn PartialReflect = &123_i32;
541        let b: &dyn PartialReflect = &123_i32;
542        let c: &dyn PartialReflect = &321_i32;
543        assert!(a.reflect_partial_eq(b).unwrap_or_default());
544        assert!(!a.reflect_partial_eq(c).unwrap_or_default());
545    }
546
547    #[test]
548    fn should_partial_eq_f32() {
549        let a: &dyn PartialReflect = &PI;
550        let b: &dyn PartialReflect = &PI;
551        let c: &dyn PartialReflect = &TAU;
552        assert!(a.reflect_partial_eq(b).unwrap_or_default());
553        assert!(!a.reflect_partial_eq(c).unwrap_or_default());
554    }
555
556    #[test]
557    fn static_str_should_from_reflect() {
558        let expected = "Hello, World!";
559        let output = <&'static str as FromReflect>::from_reflect(&expected).unwrap();
560        assert_eq!(expected, output);
561    }
562}