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}