bevy_reflect/
lib.rs

1// FIXME(3492): remove once docs are ready
2#![allow(missing_docs)]
3#![cfg_attr(docsrs, feature(doc_auto_cfg))]
4#![doc(
5    html_logo_url = "https://bevyengine.org/assets/icon.png",
6    html_favicon_url = "https://bevyengine.org/assets/icon.png"
7)]
8
9//! Reflection in Rust.
10//!
11//! [Reflection] is a powerful tool provided within many programming languages
12//! that allows for meta-programming: using information _about_ the program to
13//! _affect_ the program.
14//! In other words, reflection allows us to inspect the program itself, its
15//! syntax, and its type information at runtime.
16//!
17//! This crate adds this missing reflection functionality to Rust.
18//! Though it was made with the [Bevy] game engine in mind,
19//! it's a general-purpose solution that can be used in any Rust project.
20//!
21//! At a very high level, this crate allows you to:
22//! * Dynamically interact with Rust values
23//! * Access type metadata at runtime
24//! * Serialize and deserialize (i.e. save and load) data
25//!
26//! It's important to note that because of missing features in Rust,
27//! there are some [limitations] with this crate.
28//!
29//! # The `Reflect` Trait
30//!
31//! At the core of [`bevy_reflect`] is the [`Reflect`] trait.
32//!
33//! One of its primary purposes is to allow all implementors to be passed around
34//! as a `dyn Reflect` trait object.
35//! This allows any such type to be operated upon completely dynamically (at a small [runtime cost]).
36//!
37//! Implementing the trait is easily done using the provided [derive macro]:
38//!
39//! ```
40//! # use bevy_reflect::Reflect;
41//! #[derive(Reflect)]
42//! struct MyStruct {
43//!   foo: i32
44//! }
45//! ```
46//!
47//! This will automatically generate the implementation of `Reflect` for any struct or enum.
48//!
49//! It will also generate other very important trait implementations used for reflection:
50//! * [`GetTypeRegistration`]
51//! * [`Typed`]
52//! * [`Struct`], [`TupleStruct`], or [`Enum`] depending on the type
53//!
54//! ## Requirements
55//!
56//! We can implement `Reflect` on any type that satisfies _both_ of the following conditions:
57//! * The type implements `Any`.
58//!   This is true if and only if the type itself has a [`'static` lifetime].
59//! * All fields and sub-elements themselves implement `Reflect`
60//!   (see the [derive macro documentation] for details on how to ignore certain fields when deriving).
61//!
62//! Additionally, using the derive macro on enums requires a third condition to be met:
63//! * All fields and sub-elements must implement [`FromReflect`]—
64//! another important reflection trait discussed in a later section.
65//!
66//! # The `Reflect` Subtraits
67//!
68//! Since [`Reflect`] is meant to cover any and every type, this crate also comes with a few
69//! more traits to accompany `Reflect` and provide more specific interactions.
70//! We refer to these traits as the _reflection subtraits_ since they all have `Reflect` as a supertrait.
71//! The current list of reflection subtraits include:
72//! * [`Tuple`]
73//! * [`Array`]
74//! * [`List`]
75//! * [`Map`]
76//! * [`Struct`]
77//! * [`TupleStruct`]
78//! * [`Enum`]
79//!
80//! As mentioned previously, the last three are automatically implemented by the [derive macro].
81//!
82//! Each of these traits come with their own methods specific to their respective category.
83//! For example, we can access our struct's fields by name using the [`Struct::field`] method.
84//!
85//! ```
86//! # use bevy_reflect::{Reflect, Struct};
87//! # #[derive(Reflect)]
88//! # struct MyStruct {
89//! #   foo: i32
90//! # }
91//! let my_struct: Box<dyn Struct> = Box::new(MyStruct {
92//!   foo: 123
93//! });
94//! let foo: &dyn Reflect = my_struct.field("foo").unwrap();
95//! assert_eq!(Some(&123), foo.downcast_ref::<i32>());
96//! ```
97//!
98//! Since most data is passed around as `dyn Reflect`,
99//! the `Reflect` trait has methods for going to and from these subtraits.
100//!
101//! [`Reflect::reflect_kind`], [`Reflect::reflect_ref`], [`Reflect::reflect_mut`], and [`Reflect::reflect_owned`] all return
102//! an enum that respectively contains zero-sized, immutable, mutable, and owned access to the type as a subtrait object.
103//!
104//! For example, we can get out a `dyn Tuple` from our reflected tuple type using one of these methods.
105//!
106//! ```
107//! # use bevy_reflect::{Reflect, ReflectRef};
108//! let my_tuple: Box<dyn Reflect> = Box::new((1, 2, 3));
109//! let ReflectRef::Tuple(my_tuple) = my_tuple.reflect_ref() else { unreachable!() };
110//! assert_eq!(3, my_tuple.field_len());
111//! ```
112//!
113//! And to go back to a general-purpose `dyn Reflect`,
114//! we can just use the matching [`Reflect::as_reflect`], [`Reflect::as_reflect_mut`],
115//! or [`Reflect::into_reflect`] methods.
116//!
117//! ## Value Types
118//!
119//! Types that do not fall under one of the above subtraits,
120//! such as for primitives (e.g. `bool`, `usize`, etc.)
121//! and simple types (e.g. `String`, `Duration`),
122//! are referred to as _value_ types
123//! since methods like [`Reflect::reflect_ref`] return a [`ReflectRef::Value`] variant.
124//! While most other types contain their own `dyn Reflect` fields and data,
125//! these types generally cannot be broken down any further.
126//!
127//! # Dynamic Types
128//!
129//! Each subtrait comes with a corresponding _dynamic_ type.
130//!
131//! The available dynamic types are:
132//! * [`DynamicTuple`]
133//! * [`DynamicArray`]
134//! * [`DynamicList`]
135//! * [`DynamicMap`]
136//! * [`DynamicStruct`]
137//! * [`DynamicTupleStruct`]
138//! * [`DynamicEnum`]
139//!
140//! These dynamic types may contain any arbitrary reflected data.
141//!
142//! ```
143//! # use bevy_reflect::{DynamicStruct, Struct};
144//! let mut data = DynamicStruct::default();
145//! data.insert("foo", 123_i32);
146//! assert_eq!(Some(&123), data.field("foo").unwrap().downcast_ref::<i32>())
147//! ```
148//!
149//! They are most commonly used as "proxies" for other types,
150//! where they contain the same data as— and therefore, represent— a concrete type.
151//! The [`Reflect::clone_value`] method will return a dynamic type for all non-value types,
152//! allowing all types to essentially be "cloned".
153//! And since dynamic types themselves implement [`Reflect`],
154//! we may pass them around just like any other reflected type.
155//!
156//! ```
157//! # use bevy_reflect::{DynamicStruct, Reflect};
158//! # #[derive(Reflect)]
159//! # struct MyStruct {
160//! #   foo: i32
161//! # }
162//! let original: Box<dyn Reflect> = Box::new(MyStruct {
163//!   foo: 123
164//! });
165//!
166//! // `cloned` will be a `DynamicStruct` representing a `MyStruct`
167//! let cloned: Box<dyn Reflect> = original.clone_value();
168//! assert!(cloned.represents::<MyStruct>());
169//! assert!(cloned.is::<DynamicStruct>());
170//! ```
171//!
172//! ## Patching
173//!
174//! These dynamic types come in handy when needing to apply multiple changes to another type.
175//! This is known as "patching" and is done using the [`Reflect::apply`] and [`Reflect::try_apply`] methods.
176//!
177//! ```
178//! # use bevy_reflect::{DynamicEnum, Reflect};
179//! let mut value = Some(123_i32);
180//! let patch = DynamicEnum::new("None", ());
181//! value.apply(&patch);
182//! assert_eq!(None, value);
183//! ```
184//!
185//! ## `FromReflect`
186//!
187//! It's important to remember that dynamic types are _not_ the concrete type they may be representing.
188//! A common mistake is to treat them like such when trying to cast back to the original type
189//! or when trying to make use of a reflected trait which expects the actual type.
190//!
191//! ```should_panic
192//! # use bevy_reflect::{DynamicStruct, Reflect};
193//! # #[derive(Reflect)]
194//! # struct MyStruct {
195//! #   foo: i32
196//! # }
197//! let original: Box<dyn Reflect> = Box::new(MyStruct {
198//!   foo: 123
199//! });
200//!
201//! let cloned: Box<dyn Reflect> = original.clone_value();
202//! let value = cloned.take::<MyStruct>().unwrap(); // PANIC!
203//! ```
204//!
205//! To resolve this issue, we'll need to convert the dynamic type to the concrete one.
206//! This is where [`FromReflect`] comes in.
207//!
208//! `FromReflect` is a trait that allows an instance of a type to be generated from a
209//! dynamic representation— even partial ones.
210//! And since the [`FromReflect::from_reflect`] method takes the data by reference,
211//! this can be used to effectively clone data (to an extent).
212//!
213//! It is automatically implemented when [deriving `Reflect`] on a type unless opted out of
214//! using `#[reflect(from_reflect = false)]` on the item.
215//!
216//! ```
217//! # use bevy_reflect::{Reflect, FromReflect};
218//! #[derive(Reflect)]
219//! struct MyStruct {
220//!   foo: i32
221//! }
222//! let original: Box<dyn Reflect> = Box::new(MyStruct {
223//!   foo: 123
224//! });
225//!
226//! let cloned: Box<dyn Reflect> = original.clone_value();
227//! let value = <MyStruct as FromReflect>::from_reflect(&*cloned).unwrap(); // OK!
228//! ```
229//!
230//! When deriving, all active fields and sub-elements must also implement `FromReflect`.
231//!
232//! Fields can be given default values for when a field is missing in the passed value or even ignored.
233//! Ignored fields must either implement [`Default`] or have a default function specified
234//! using `#[reflect(default = "path::to::function")]`.
235//!
236//! See the [derive macro documentation](derive@crate::FromReflect) for details.
237//!
238//! All primitives and simple types implement `FromReflect` by relying on their [`Default`] implementation.
239//!
240//! # Path navigation
241//!
242//! The [`GetPath`] trait allows accessing arbitrary nested fields of a [`Reflect`] type.
243//!
244//! Using `GetPath`, it is possible to use a path string to access a specific field
245//! of a reflected type.
246//!
247//! ```
248//! # use bevy_reflect::{Reflect, GetPath};
249//! #[derive(Reflect)]
250//! struct MyStruct {
251//!   value: Vec<Option<u32>>
252//! }
253//!
254//! let my_struct = MyStruct {
255//!   value: vec![None, None, Some(123)],
256//! };
257//! assert_eq!(
258//!   my_struct.path::<u32>(".value[2].0").unwrap(),
259//!   &123,
260//! );
261//! ```
262//!
263//! # Type Registration
264//!
265//! This crate also comes with a [`TypeRegistry`] that can be used to store and retrieve additional type metadata at runtime,
266//! such as helper types and trait implementations.
267//!
268//! The [derive macro] for [`Reflect`] also generates an implementation of the [`GetTypeRegistration`] trait,
269//! which is used by the registry to generate a [`TypeRegistration`] struct for that type.
270//! We can then register additional [type data] we want associated with that type.
271//!
272//! For example, we can register [`ReflectDefault`] on our type so that its `Default` implementation
273//! may be used dynamically.
274//!
275//! ```
276//! # use bevy_reflect::{Reflect, TypeRegistry, prelude::ReflectDefault};
277//! #[derive(Reflect, Default)]
278//! struct MyStruct {
279//!   foo: i32
280//! }
281//! let mut registry = TypeRegistry::empty();
282//! registry.register::<MyStruct>();
283//! registry.register_type_data::<MyStruct, ReflectDefault>();
284//!
285//! let registration = registry.get(std::any::TypeId::of::<MyStruct>()).unwrap();
286//! let reflect_default = registration.data::<ReflectDefault>().unwrap();
287//!
288//! let new_value: Box<dyn Reflect> = reflect_default.default();
289//! assert!(new_value.is::<MyStruct>());
290//! ```
291//!
292//! Because this operation is so common, the derive macro actually has a shorthand for it.
293//! By using the `#[reflect(Trait)]` attribute, the derive macro will automatically register a matching,
294//! in-scope `ReflectTrait` type within the `GetTypeRegistration` implementation.
295//!
296//! ```
297//! use bevy_reflect::prelude::{Reflect, ReflectDefault};
298//!
299//! #[derive(Reflect, Default)]
300//! #[reflect(Default)]
301//! struct MyStruct {
302//!   foo: i32
303//! }
304//! ```
305//!
306//! ## Reflecting Traits
307//!
308//! Type data doesn't have to be tied to a trait, but it's often extremely useful to create trait type data.
309//! These allow traits to be used directly on a `dyn Reflect` while utilizing the underlying type's implementation.
310//!
311//! For any [object-safe] trait, we can easily generate a corresponding `ReflectTrait` type for our trait
312//! using the [`#[reflect_trait]`](reflect_trait) macro.
313//!
314//! ```
315//! # use bevy_reflect::{Reflect, reflect_trait, TypeRegistry};
316//! #[reflect_trait] // Generates a `ReflectMyTrait` type
317//! pub trait MyTrait {}
318//! impl<T: Reflect> MyTrait for T {}
319//!
320//! let mut registry = TypeRegistry::new();
321//! registry.register_type_data::<i32, ReflectMyTrait>();
322//! ```
323//!
324//! The generated type data can be used to convert a valid `dyn Reflect` into a `dyn MyTrait`.
325//! See the [trait reflection example](https://github.com/bevyengine/bevy/blob/latest/examples/reflection/trait_reflection.rs)
326//! for more information and usage details.
327//!
328//! # Serialization
329//!
330//! By using reflection, we are also able to get serialization capabilities for free.
331//! In fact, using [`bevy_reflect`] can result in faster compile times and reduced code generation over
332//! directly deriving the [`serde`] traits.
333//!
334//! The way it works is by moving the serialization logic into common serializers and deserializers:
335//! * [`ReflectSerializer`]
336//! * [`TypedReflectSerializer`]
337//! * [`ReflectDeserializer`]
338//! * [`TypedReflectDeserializer`]
339//!
340//! All of these structs require a reference to the [registry] so that [type information] can be retrieved,
341//! as well as registered type data, such as [`ReflectSerialize`] and [`ReflectDeserialize`].
342//!
343//! The general entry point are the "untyped" versions of these structs.
344//! These will automatically extract the type information and pass them into their respective "typed" version.
345//!
346//! The output of the `ReflectSerializer` will be a map, where the key is the [type path]
347//! and the value is the serialized data.
348//! The `TypedReflectSerializer` will simply output the serialized data.
349//!
350//! The `ReflectDeserializer` can be used to deserialize this map and return a `Box<dyn Reflect>`,
351//! where the underlying type will be a dynamic type representing some concrete type (except for value types).
352//!
353//! Again, it's important to remember that dynamic types may need to be converted to their concrete counterparts
354//! in order to be used in certain cases.
355//! This can be achieved using [`FromReflect`].
356//!
357//! ```
358//! # use serde::de::DeserializeSeed;
359//! # use bevy_reflect::{
360//! #     serde::{ReflectSerializer, ReflectDeserializer},
361//! #     Reflect, FromReflect, TypeRegistry
362//! # };
363//! #[derive(Reflect, PartialEq, Debug)]
364//! struct MyStruct {
365//!   foo: i32
366//! }
367//!
368//! let original_value = MyStruct {
369//!   foo: 123
370//! };
371//!
372//! // Register
373//! let mut registry = TypeRegistry::new();
374//! registry.register::<MyStruct>();
375//!
376//! // Serialize
377//! let reflect_serializer = ReflectSerializer::new(&original_value, &registry);
378//! let serialized_value: String = ron::to_string(&reflect_serializer).unwrap();
379//!
380//! // Deserialize
381//! let reflect_deserializer = ReflectDeserializer::new(&registry);
382//! let deserialized_value: Box<dyn Reflect> = reflect_deserializer.deserialize(
383//!   &mut ron::Deserializer::from_str(&serialized_value).unwrap()
384//! ).unwrap();
385//!
386//! // Convert
387//! let converted_value = <MyStruct as FromReflect>::from_reflect(&*deserialized_value).unwrap();
388//!
389//! assert_eq!(original_value, converted_value);
390//! ```
391//!
392//! # Limitations
393//!
394//! While this crate offers a lot in terms of adding reflection to Rust,
395//! it does come with some limitations that don't make it as featureful as reflection
396//! in other programming languages.
397//!
398//! ## Non-Static Lifetimes
399//!
400//! One of the most obvious limitations is the `'static` requirement.
401//! Rust requires fields to define a lifetime for referenced data,
402//! but [`Reflect`] requires all types to have a `'static` lifetime.
403//! This makes it impossible to reflect any type with non-static borrowed data.
404//!
405//! ## Function Reflection
406//!
407//! Another limitation is the inability to fully reflect functions and methods.
408//! Most languages offer some way of calling methods dynamically,
409//! but Rust makes this very difficult to do.
410//! For non-generic methods, this can be done by registering custom [type data] that
411//! contains function pointers.
412//! For generic methods, the same can be done but will typically require manual monomorphization
413//! (i.e. manually specifying the types the generic method can take).
414//!
415//! ## Manual Registration
416//!
417//! Since Rust doesn't provide built-in support for running initialization code before `main`,
418//! there is no way for `bevy_reflect` to automatically register types into the [type registry].
419//! This means types must manually be registered, including their desired monomorphized
420//! representations if generic.
421//!
422//! # Features
423//!
424//! ## `bevy`
425//!
426//! | Default | Dependencies                              |
427//! | :-----: | :---------------------------------------: |
428//! | ❌      | [`bevy_math`], [`glam`], [`smallvec`] |
429//!
430//! This feature makes it so that the appropriate reflection traits are implemented on all the types
431//! necessary for the [Bevy] game engine.
432//! enables the optional dependencies: [`bevy_math`], [`glam`], and [`smallvec`].
433//! These dependencies are used by the [Bevy] game engine and must define their reflection implementations
434//! within this crate due to Rust's [orphan rule].
435//!
436//! ## `documentation`
437//!
438//! | Default | Dependencies                                  |
439//! | :-----: | :-------------------------------------------: |
440//! | ❌      | [`bevy_reflect_derive/documentation`]         |
441//!
442//! This feature enables capturing doc comments as strings for items that [derive `Reflect`].
443//! Documentation information can then be accessed at runtime on the [`TypeInfo`] of that item.
444//!
445//! This can be useful for generating documentation for scripting language interop or
446//! for displaying tooltips in an editor.
447//!
448//! [Reflection]: https://en.wikipedia.org/wiki/Reflective_programming
449//! [Bevy]: https://bevyengine.org/
450//! [limitations]: #limitations
451//! [`bevy_reflect`]: crate
452//! [runtime cost]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch
453//! [derive macro]: derive@crate::Reflect
454//! [`'static` lifetime]: https://doc.rust-lang.org/rust-by-example/scope/lifetime/static_lifetime.html#trait-bound
455//! [derive macro documentation]: derive@crate::Reflect
456//! [deriving `Reflect`]: derive@crate::Reflect
457//! [type data]: TypeData
458//! [`ReflectDefault`]: std_traits::ReflectDefault
459//! [object-safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety
460//! [`serde`]: ::serde
461//! [`ReflectSerializer`]: serde::ReflectSerializer
462//! [`TypedReflectSerializer`]: serde::TypedReflectSerializer
463//! [`ReflectDeserializer`]: serde::ReflectDeserializer
464//! [`TypedReflectDeserializer`]: serde::TypedReflectDeserializer
465//! [registry]: TypeRegistry
466//! [type information]: TypeInfo
467//! [type path]: TypePath
468//! [type registry]: TypeRegistry
469//! [`bevy_math`]: https://docs.rs/bevy_math/latest/bevy_math/
470//! [`glam`]: https://docs.rs/glam/latest/glam/
471//! [`smallvec`]: https://docs.rs/smallvec/latest/smallvec/
472//! [orphan rule]: https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type:~:text=But%20we%20can%E2%80%99t,implementation%20to%20use.
473//! [`bevy_reflect_derive/documentation`]: bevy_reflect_derive
474//! [derive `Reflect`]: derive@crate::Reflect
475
476mod array;
477mod fields;
478mod from_reflect;
479mod list;
480mod map;
481mod path;
482mod reflect;
483mod struct_trait;
484mod tuple;
485mod tuple_struct;
486mod type_info;
487mod type_path;
488mod type_registry;
489
490mod impls {
491    #[cfg(feature = "glam")]
492    mod glam;
493    #[cfg(feature = "petgraph")]
494    mod petgraph;
495    #[cfg(feature = "smallvec")]
496    mod smallvec;
497    #[cfg(feature = "smol_str")]
498    mod smol_str;
499
500    mod std;
501    #[cfg(feature = "uuid")]
502    mod uuid;
503}
504
505pub mod attributes;
506mod enums;
507pub mod serde;
508pub mod std_traits;
509pub mod utility;
510
511pub mod prelude {
512    pub use crate::std_traits::*;
513    #[doc(hidden)]
514    pub use crate::{
515        reflect_trait, FromReflect, GetField, GetPath, GetTupleStructField, Reflect,
516        ReflectDeserialize, ReflectFromReflect, ReflectPath, ReflectSerialize, Struct, TupleStruct,
517        TypePath,
518    };
519}
520
521pub use array::*;
522pub use enums::*;
523pub use fields::*;
524pub use from_reflect::*;
525pub use list::*;
526pub use map::*;
527pub use path::*;
528pub use reflect::*;
529pub use struct_trait::*;
530pub use tuple::*;
531pub use tuple_struct::*;
532pub use type_info::*;
533pub use type_path::*;
534pub use type_registry::*;
535
536pub use bevy_reflect_derive::*;
537pub use erased_serde;
538
539extern crate alloc;
540
541/// Exports used by the reflection macros.
542///
543/// These are not meant to be used directly and are subject to breaking changes.
544#[doc(hidden)]
545pub mod __macro_exports {
546    use crate::{
547        DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicStruct, DynamicTuple,
548        DynamicTupleStruct, GetTypeRegistration, TypeRegistry,
549    };
550
551    /// A wrapper trait around [`GetTypeRegistration`].
552    ///
553    /// This trait is used by the derive macro to recursively register all type dependencies.
554    /// It's used instead of `GetTypeRegistration` directly to avoid making dynamic types also
555    /// implement `GetTypeRegistration` in order to be used as active fields.
556    ///
557    /// This trait has a blanket implementation for all types that implement `GetTypeRegistration`
558    /// and manual implementations for all dynamic types (which simply do nothing).
559    pub trait RegisterForReflection {
560        #[allow(unused_variables)]
561        fn __register(registry: &mut TypeRegistry) {}
562    }
563
564    impl<T: GetTypeRegistration> RegisterForReflection for T {
565        fn __register(registry: &mut TypeRegistry) {
566            registry.register::<T>();
567        }
568    }
569
570    impl RegisterForReflection for DynamicEnum {}
571
572    impl RegisterForReflection for DynamicTupleStruct {}
573
574    impl RegisterForReflection for DynamicStruct {}
575
576    impl RegisterForReflection for DynamicMap {}
577
578    impl RegisterForReflection for DynamicList {}
579
580    impl RegisterForReflection for DynamicArray {}
581
582    impl RegisterForReflection for DynamicTuple {}
583}
584
585#[cfg(test)]
586#[allow(clippy::disallowed_types, clippy::approx_constant)]
587mod tests {
588    use ::serde::{de::DeserializeSeed, Deserialize, Serialize};
589    use bevy_utils::HashMap;
590    use ron::{
591        ser::{to_string_pretty, PrettyConfig},
592        Deserializer,
593    };
594    use static_assertions::{assert_impl_all, assert_not_impl_all};
595    use std::{
596        any::TypeId,
597        borrow::Cow,
598        fmt::{Debug, Formatter},
599        marker::PhantomData,
600    };
601
602    use super::prelude::*;
603    use super::*;
604    use crate as bevy_reflect;
605    use crate::serde::{ReflectDeserializer, ReflectSerializer};
606    use crate::utility::GenericTypePathCell;
607
608    #[test]
609    fn try_apply_should_detect_kinds() {
610        #[derive(Reflect, Debug)]
611        struct Struct {
612            a: u32,
613            b: f32,
614        }
615
616        #[derive(Reflect, Debug)]
617        enum Enum {
618            A,
619            B(u32),
620        }
621
622        let mut struct_target = Struct {
623            a: 0xDEADBEEF,
624            b: 3.14,
625        };
626
627        let mut enum_target = Enum::A;
628
629        let array_src = [8, 0, 8];
630
631        let result = struct_target.try_apply(&enum_target);
632        assert!(
633            matches!(
634                result,
635                Err(ApplyError::MismatchedKinds {
636                    from_kind: ReflectKind::Enum,
637                    to_kind: ReflectKind::Struct
638                })
639            ),
640            "result was {result:?}"
641        );
642
643        let result = enum_target.try_apply(&array_src);
644        assert!(
645            matches!(
646                result,
647                Err(ApplyError::MismatchedKinds {
648                    from_kind: ReflectKind::Array,
649                    to_kind: ReflectKind::Enum
650                })
651            ),
652            "result was {result:?}"
653        );
654    }
655
656    #[test]
657    fn reflect_struct() {
658        #[derive(Reflect)]
659        struct Foo {
660            a: u32,
661            b: f32,
662            c: Bar,
663        }
664        #[derive(Reflect)]
665        struct Bar {
666            x: u32,
667        }
668
669        let mut foo = Foo {
670            a: 42,
671            b: 3.14,
672            c: Bar { x: 1 },
673        };
674
675        let a = *foo.get_field::<u32>("a").unwrap();
676        assert_eq!(a, 42);
677
678        *foo.get_field_mut::<u32>("a").unwrap() += 1;
679        assert_eq!(foo.a, 43);
680
681        let bar = foo.get_field::<Bar>("c").unwrap();
682        assert_eq!(bar.x, 1);
683
684        // nested retrieval
685        let c = foo.field("c").unwrap();
686        if let ReflectRef::Struct(value) = c.reflect_ref() {
687            assert_eq!(*value.get_field::<u32>("x").unwrap(), 1);
688        } else {
689            panic!("Expected a struct.");
690        }
691
692        // patch Foo with a dynamic struct
693        let mut dynamic_struct = DynamicStruct::default();
694        dynamic_struct.insert("a", 123u32);
695        dynamic_struct.insert("should_be_ignored", 456);
696
697        foo.apply(&dynamic_struct);
698        assert_eq!(foo.a, 123);
699    }
700
701    #[test]
702    fn reflect_map() {
703        #[derive(Reflect, Hash)]
704        #[reflect(Hash)]
705        struct Foo {
706            a: u32,
707            b: String,
708        }
709
710        let key_a = Foo {
711            a: 1,
712            b: "k1".to_string(),
713        };
714
715        let key_b = Foo {
716            a: 1,
717            b: "k1".to_string(),
718        };
719
720        let key_c = Foo {
721            a: 3,
722            b: "k3".to_string(),
723        };
724
725        let mut map = DynamicMap::default();
726        map.insert(key_a, 10u32);
727        assert_eq!(10, *map.get(&key_b).unwrap().downcast_ref::<u32>().unwrap());
728        assert!(map.get(&key_c).is_none());
729        *map.get_mut(&key_b).unwrap().downcast_mut::<u32>().unwrap() = 20;
730        assert_eq!(20, *map.get(&key_b).unwrap().downcast_ref::<u32>().unwrap());
731    }
732
733    #[test]
734    #[allow(clippy::disallowed_types)]
735    fn reflect_unit_struct() {
736        #[derive(Reflect)]
737        struct Foo(u32, u64);
738
739        let mut foo = Foo(1, 2);
740        assert_eq!(1, *foo.get_field::<u32>(0).unwrap());
741        assert_eq!(2, *foo.get_field::<u64>(1).unwrap());
742
743        let mut patch = DynamicTupleStruct::default();
744        patch.insert(3u32);
745        patch.insert(4u64);
746        assert_eq!(3, *patch.field(0).unwrap().downcast_ref::<u32>().unwrap());
747        assert_eq!(4, *patch.field(1).unwrap().downcast_ref::<u64>().unwrap());
748
749        foo.apply(&patch);
750        assert_eq!(3, foo.0);
751        assert_eq!(4, foo.1);
752
753        let mut iter = patch.iter_fields();
754        assert_eq!(3, *iter.next().unwrap().downcast_ref::<u32>().unwrap());
755        assert_eq!(4, *iter.next().unwrap().downcast_ref::<u64>().unwrap());
756    }
757
758    #[test]
759    #[should_panic(expected = "the given key bevy_reflect::tests::Foo does not support hashing")]
760    fn reflect_map_no_hash() {
761        #[derive(Reflect)]
762        struct Foo {
763            a: u32,
764        }
765
766        let foo = Foo { a: 1 };
767
768        let mut map = DynamicMap::default();
769        map.insert(foo, 10u32);
770    }
771
772    #[test]
773    fn reflect_ignore() {
774        #[derive(Reflect)]
775        struct Foo {
776            a: u32,
777            #[reflect(ignore)]
778            _b: u32,
779        }
780
781        let foo = Foo { a: 1, _b: 2 };
782
783        let values: Vec<u32> = foo
784            .iter_fields()
785            .map(|value| *value.downcast_ref::<u32>().unwrap())
786            .collect();
787        assert_eq!(values, vec![1]);
788    }
789
790    #[test]
791    fn should_call_from_reflect_dynamically() {
792        #[derive(Reflect)]
793        struct MyStruct {
794            foo: usize,
795        }
796
797        // Register
798        let mut registry = TypeRegistry::default();
799        registry.register::<MyStruct>();
800
801        // Get type data
802        let type_id = TypeId::of::<MyStruct>();
803        let rfr = registry
804            .get_type_data::<ReflectFromReflect>(type_id)
805            .expect("the FromReflect trait should be registered");
806
807        // Call from_reflect
808        let mut dynamic_struct = DynamicStruct::default();
809        dynamic_struct.insert("foo", 123usize);
810        let reflected = rfr
811            .from_reflect(&dynamic_struct)
812            .expect("the type should be properly reflected");
813
814        // Assert
815        let expected = MyStruct { foo: 123 };
816        assert!(expected
817            .reflect_partial_eq(reflected.as_ref())
818            .unwrap_or_default());
819        let not_expected = MyStruct { foo: 321 };
820        assert!(!not_expected
821            .reflect_partial_eq(reflected.as_ref())
822            .unwrap_or_default());
823    }
824
825    #[test]
826    fn from_reflect_should_allow_ignored_unnamed_fields() {
827        #[derive(Reflect, Eq, PartialEq, Debug)]
828        struct MyTupleStruct(i8, #[reflect(ignore)] i16, i32);
829
830        let expected = MyTupleStruct(1, 0, 3);
831
832        let mut dyn_tuple_struct = DynamicTupleStruct::default();
833        dyn_tuple_struct.insert(1_i8);
834        dyn_tuple_struct.insert(3_i32);
835        let my_tuple_struct = <MyTupleStruct as FromReflect>::from_reflect(&dyn_tuple_struct);
836
837        assert_eq!(Some(expected), my_tuple_struct);
838
839        #[derive(Reflect, Eq, PartialEq, Debug)]
840        enum MyEnum {
841            Tuple(i8, #[reflect(ignore)] i16, i32),
842        }
843
844        let expected = MyEnum::Tuple(1, 0, 3);
845
846        let mut dyn_tuple = DynamicTuple::default();
847        dyn_tuple.insert(1_i8);
848        dyn_tuple.insert(3_i32);
849
850        let mut dyn_enum = DynamicEnum::default();
851        dyn_enum.set_variant("Tuple", dyn_tuple);
852
853        let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
854
855        assert_eq!(Some(expected), my_enum);
856    }
857
858    #[test]
859    fn from_reflect_should_use_default_field_attributes() {
860        #[derive(Reflect, Eq, PartialEq, Debug)]
861        struct MyStruct {
862            // Use `Default::default()`
863            // Note that this isn't an ignored field
864            #[reflect(default)]
865            foo: String,
866
867            // Use `get_bar_default()`
868            #[reflect(ignore)]
869            #[reflect(default = "get_bar_default")]
870            bar: NotReflect,
871
872            // Ensure attributes can be combined
873            #[reflect(ignore, default = "get_bar_default")]
874            baz: NotReflect,
875        }
876
877        #[derive(Eq, PartialEq, Debug)]
878        struct NotReflect(usize);
879
880        fn get_bar_default() -> NotReflect {
881            NotReflect(123)
882        }
883
884        let expected = MyStruct {
885            foo: String::default(),
886            bar: NotReflect(123),
887            baz: NotReflect(123),
888        };
889
890        let dyn_struct = DynamicStruct::default();
891        let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
892
893        assert_eq!(Some(expected), my_struct);
894    }
895
896    #[test]
897    fn from_reflect_should_use_default_variant_field_attributes() {
898        #[derive(Reflect, Eq, PartialEq, Debug)]
899        enum MyEnum {
900            Foo(#[reflect(default)] String),
901            Bar {
902                #[reflect(default = "get_baz_default")]
903                #[reflect(ignore)]
904                baz: usize,
905            },
906        }
907
908        fn get_baz_default() -> usize {
909            123
910        }
911
912        let expected = MyEnum::Foo(String::default());
913
914        let dyn_enum = DynamicEnum::new("Foo", DynamicTuple::default());
915        let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
916
917        assert_eq!(Some(expected), my_enum);
918
919        let expected = MyEnum::Bar {
920            baz: get_baz_default(),
921        };
922
923        let dyn_enum = DynamicEnum::new("Bar", DynamicStruct::default());
924        let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
925
926        assert_eq!(Some(expected), my_enum);
927    }
928
929    #[test]
930    fn from_reflect_should_use_default_container_attribute() {
931        #[derive(Reflect, Eq, PartialEq, Debug)]
932        #[reflect(Default)]
933        struct MyStruct {
934            foo: String,
935            #[reflect(ignore)]
936            bar: usize,
937        }
938
939        impl Default for MyStruct {
940            fn default() -> Self {
941                Self {
942                    foo: String::from("Hello"),
943                    bar: 123,
944                }
945            }
946        }
947
948        let expected = MyStruct {
949            foo: String::from("Hello"),
950            bar: 123,
951        };
952
953        let dyn_struct = DynamicStruct::default();
954        let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
955
956        assert_eq!(Some(expected), my_struct);
957    }
958
959    #[test]
960    fn reflect_complex_patch() {
961        #[derive(Reflect, Eq, PartialEq, Debug)]
962        #[reflect(PartialEq)]
963        struct Foo {
964            a: u32,
965            #[reflect(ignore)]
966            _b: u32,
967            c: Vec<isize>,
968            d: HashMap<usize, i8>,
969            e: Bar,
970            f: (i32, Vec<isize>, Bar),
971            g: Vec<(Baz, HashMap<usize, Bar>)>,
972            h: [u32; 2],
973        }
974
975        #[derive(Reflect, Eq, PartialEq, Clone, Debug)]
976        #[reflect(PartialEq)]
977        struct Bar {
978            x: u32,
979        }
980
981        #[derive(Reflect, Eq, PartialEq, Debug)]
982        struct Baz(String);
983
984        let mut hash_map = HashMap::default();
985        hash_map.insert(1, 1);
986        hash_map.insert(2, 2);
987
988        let mut hash_map_baz = HashMap::default();
989        hash_map_baz.insert(1, Bar { x: 0 });
990
991        let mut foo = Foo {
992            a: 1,
993            _b: 1,
994            c: vec![1, 2],
995            d: hash_map,
996            e: Bar { x: 1 },
997            f: (1, vec![1, 2], Bar { x: 1 }),
998            g: vec![(Baz("string".to_string()), hash_map_baz)],
999            h: [2; 2],
1000        };
1001
1002        let mut foo_patch = DynamicStruct::default();
1003        foo_patch.insert("a", 2u32);
1004        foo_patch.insert("b", 2u32); // this should be ignored
1005
1006        let mut list = DynamicList::default();
1007        list.push(3isize);
1008        list.push(4isize);
1009        list.push(5isize);
1010        foo_patch.insert("c", list.clone_dynamic());
1011
1012        let mut map = DynamicMap::default();
1013        map.insert(2usize, 3i8);
1014        map.insert(3usize, 4i8);
1015        foo_patch.insert("d", map);
1016
1017        let mut bar_patch = DynamicStruct::default();
1018        bar_patch.insert("x", 2u32);
1019        foo_patch.insert("e", bar_patch.clone_dynamic());
1020
1021        let mut tuple = DynamicTuple::default();
1022        tuple.insert(2i32);
1023        tuple.insert(list);
1024        tuple.insert(bar_patch);
1025        foo_patch.insert("f", tuple);
1026
1027        let mut composite = DynamicList::default();
1028        composite.push({
1029            let mut tuple = DynamicTuple::default();
1030            tuple.insert({
1031                let mut tuple_struct = DynamicTupleStruct::default();
1032                tuple_struct.insert("new_string".to_string());
1033                tuple_struct
1034            });
1035            tuple.insert({
1036                let mut map = DynamicMap::default();
1037                map.insert(1usize, {
1038                    let mut struct_ = DynamicStruct::default();
1039                    struct_.insert("x", 7u32);
1040                    struct_
1041                });
1042                map
1043            });
1044            tuple
1045        });
1046        foo_patch.insert("g", composite);
1047
1048        let array = DynamicArray::from_vec(vec![2u32, 2u32]);
1049        foo_patch.insert("h", array);
1050
1051        foo.apply(&foo_patch);
1052
1053        let mut hash_map = HashMap::default();
1054        hash_map.insert(1, 1);
1055        hash_map.insert(2, 3);
1056        hash_map.insert(3, 4);
1057
1058        let mut hash_map_baz = HashMap::default();
1059        hash_map_baz.insert(1, Bar { x: 7 });
1060
1061        let expected_foo = Foo {
1062            a: 2,
1063            _b: 1,
1064            c: vec![3, 4, 5],
1065            d: hash_map,
1066            e: Bar { x: 2 },
1067            f: (2, vec![3, 4, 5], Bar { x: 2 }),
1068            g: vec![(Baz("new_string".to_string()), hash_map_baz.clone())],
1069            h: [2; 2],
1070        };
1071
1072        assert_eq!(foo, expected_foo);
1073
1074        let new_foo = Foo::from_reflect(&foo_patch)
1075            .expect("error while creating a concrete type from a dynamic type");
1076
1077        let mut hash_map = HashMap::default();
1078        hash_map.insert(2, 3);
1079        hash_map.insert(3, 4);
1080
1081        let expected_new_foo = Foo {
1082            a: 2,
1083            _b: 0,
1084            c: vec![3, 4, 5],
1085            d: hash_map,
1086            e: Bar { x: 2 },
1087            f: (2, vec![3, 4, 5], Bar { x: 2 }),
1088            g: vec![(Baz("new_string".to_string()), hash_map_baz)],
1089            h: [2; 2],
1090        };
1091
1092        assert_eq!(new_foo, expected_new_foo);
1093    }
1094
1095    #[test]
1096    fn should_auto_register_fields() {
1097        #[derive(Reflect)]
1098        struct Foo {
1099            bar: Bar,
1100        }
1101
1102        #[derive(Reflect)]
1103        enum Bar {
1104            Variant(Baz),
1105        }
1106
1107        #[derive(Reflect)]
1108        struct Baz(usize);
1109
1110        // === Basic === //
1111        let mut registry = TypeRegistry::empty();
1112        registry.register::<Foo>();
1113
1114        assert!(
1115            registry.contains(TypeId::of::<Bar>()),
1116            "registry should contain auto-registered `Bar` from `Foo`"
1117        );
1118
1119        // === Option === //
1120        let mut registry = TypeRegistry::empty();
1121        registry.register::<Option<Foo>>();
1122
1123        assert!(
1124            registry.contains(TypeId::of::<Bar>()),
1125            "registry should contain auto-registered `Bar` from `Option<Foo>`"
1126        );
1127
1128        // === Tuple === //
1129        let mut registry = TypeRegistry::empty();
1130        registry.register::<(Foo, Foo)>();
1131
1132        assert!(
1133            registry.contains(TypeId::of::<Bar>()),
1134            "registry should contain auto-registered `Bar` from `(Foo, Foo)`"
1135        );
1136
1137        // === Array === //
1138        let mut registry = TypeRegistry::empty();
1139        registry.register::<[Foo; 3]>();
1140
1141        assert!(
1142            registry.contains(TypeId::of::<Bar>()),
1143            "registry should contain auto-registered `Bar` from `[Foo; 3]`"
1144        );
1145
1146        // === Vec === //
1147        let mut registry = TypeRegistry::empty();
1148        registry.register::<Vec<Foo>>();
1149
1150        assert!(
1151            registry.contains(TypeId::of::<Bar>()),
1152            "registry should contain auto-registered `Bar` from `Vec<Foo>`"
1153        );
1154
1155        // === HashMap === //
1156        let mut registry = TypeRegistry::empty();
1157        registry.register::<HashMap<i32, Foo>>();
1158
1159        assert!(
1160            registry.contains(TypeId::of::<Bar>()),
1161            "registry should contain auto-registered `Bar` from `HashMap<i32, Foo>`"
1162        );
1163    }
1164
1165    #[test]
1166    fn should_allow_dynamic_fields() {
1167        #[derive(Reflect)]
1168        #[reflect(from_reflect = false)]
1169        struct MyStruct(
1170            DynamicEnum,
1171            DynamicTupleStruct,
1172            DynamicStruct,
1173            DynamicMap,
1174            DynamicList,
1175            DynamicArray,
1176            DynamicTuple,
1177            i32,
1178        );
1179
1180        assert_impl_all!(MyStruct: Reflect, GetTypeRegistration);
1181
1182        let mut registry = TypeRegistry::empty();
1183        registry.register::<MyStruct>();
1184
1185        assert_eq!(2, registry.iter().count());
1186        assert!(registry.contains(TypeId::of::<MyStruct>()));
1187        assert!(registry.contains(TypeId::of::<i32>()));
1188    }
1189
1190    #[test]
1191    fn should_not_auto_register_existing_types() {
1192        #[derive(Reflect)]
1193        struct Foo {
1194            bar: Bar,
1195        }
1196
1197        #[derive(Reflect, Default)]
1198        struct Bar(usize);
1199
1200        let mut registry = TypeRegistry::empty();
1201        registry.register::<Bar>();
1202        registry.register_type_data::<Bar, ReflectDefault>();
1203        registry.register::<Foo>();
1204
1205        assert!(
1206            registry
1207                .get_type_data::<ReflectDefault>(TypeId::of::<Bar>())
1208                .is_some(),
1209            "registry should contain existing registration for `Bar`"
1210        );
1211    }
1212
1213    #[test]
1214    fn reflect_serialize() {
1215        #[derive(Reflect)]
1216        struct Foo {
1217            a: u32,
1218            #[reflect(ignore)]
1219            _b: u32,
1220            c: Vec<isize>,
1221            d: HashMap<usize, i8>,
1222            e: Bar,
1223            f: String,
1224            g: (i32, Vec<isize>, Bar),
1225            h: [u32; 2],
1226        }
1227
1228        #[derive(Reflect, Serialize, Deserialize)]
1229        #[reflect(Serialize, Deserialize)]
1230        struct Bar {
1231            x: u32,
1232        }
1233
1234        let mut hash_map = HashMap::default();
1235        hash_map.insert(1, 1);
1236        hash_map.insert(2, 2);
1237        let foo = Foo {
1238            a: 1,
1239            _b: 1,
1240            c: vec![1, 2],
1241            d: hash_map,
1242            e: Bar { x: 1 },
1243            f: "hi".to_string(),
1244            g: (1, vec![1, 2], Bar { x: 1 }),
1245            h: [2; 2],
1246        };
1247
1248        let mut registry = TypeRegistry::default();
1249        registry.register::<u32>();
1250        registry.register::<i8>();
1251        registry.register::<i32>();
1252        registry.register::<usize>();
1253        registry.register::<isize>();
1254        registry.register::<Foo>();
1255        registry.register::<Bar>();
1256        registry.register::<String>();
1257        registry.register::<Vec<isize>>();
1258        registry.register::<HashMap<usize, i8>>();
1259        registry.register::<(i32, Vec<isize>, Bar)>();
1260        registry.register::<[u32; 2]>();
1261
1262        let serializer = ReflectSerializer::new(&foo, &registry);
1263        let serialized = to_string_pretty(&serializer, PrettyConfig::default()).unwrap();
1264
1265        let mut deserializer = Deserializer::from_str(&serialized).unwrap();
1266        let reflect_deserializer = ReflectDeserializer::new(&registry);
1267        let value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
1268        let dynamic_struct = value.take::<DynamicStruct>().unwrap();
1269
1270        assert!(foo.reflect_partial_eq(&dynamic_struct).unwrap());
1271    }
1272
1273    #[test]
1274    fn reflect_downcast() {
1275        #[derive(Reflect, Clone, Debug, PartialEq)]
1276        struct Bar {
1277            y: u8,
1278        }
1279
1280        #[derive(Reflect, Clone, Debug, PartialEq)]
1281        struct Foo {
1282            x: i32,
1283            s: String,
1284            b: Bar,
1285            u: usize,
1286            t: ([f32; 3], String),
1287            v: Cow<'static, str>,
1288            w: Cow<'static, [u8]>,
1289        }
1290
1291        let foo = Foo {
1292            x: 123,
1293            s: "String".to_string(),
1294            b: Bar { y: 255 },
1295            u: 1111111111111,
1296            t: ([3.0, 2.0, 1.0], "Tuple String".to_string()),
1297            v: Cow::Owned("Cow String".to_string()),
1298            w: Cow::Owned(vec![1, 2, 3]),
1299        };
1300
1301        let foo2: Box<dyn Reflect> = Box::new(foo.clone());
1302
1303        assert_eq!(foo, *foo2.downcast::<Foo>().unwrap());
1304    }
1305
1306    #[test]
1307    fn should_drain_fields() {
1308        let array_value: Box<dyn Array> = Box::new([123_i32, 321_i32]);
1309        let fields = array_value.drain();
1310        assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1311        assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1312
1313        let list_value: Box<dyn List> = Box::new(vec![123_i32, 321_i32]);
1314        let fields = list_value.drain();
1315        assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1316        assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1317
1318        let tuple_value: Box<dyn Tuple> = Box::new((123_i32, 321_i32));
1319        let fields = tuple_value.drain();
1320        assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1321        assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1322
1323        let map_value: Box<dyn Map> = Box::new(HashMap::from([(123_i32, 321_i32)]));
1324        let fields = map_value.drain();
1325        assert!(fields[0].0.reflect_partial_eq(&123_i32).unwrap_or_default());
1326        assert!(fields[0].1.reflect_partial_eq(&321_i32).unwrap_or_default());
1327    }
1328
1329    #[test]
1330    fn reflect_take() {
1331        #[derive(Reflect, Debug, PartialEq)]
1332        #[reflect(PartialEq)]
1333        struct Bar {
1334            x: u32,
1335        }
1336
1337        let x: Box<dyn Reflect> = Box::new(Bar { x: 2 });
1338        let y = x.take::<Bar>().unwrap();
1339        assert_eq!(y, Bar { x: 2 });
1340    }
1341
1342    #[test]
1343    fn not_dynamic_names() {
1344        let list = Vec::<usize>::new();
1345        let dyn_list = list.clone_dynamic();
1346        assert_ne!(dyn_list.reflect_type_path(), Vec::<usize>::type_path());
1347
1348        let array = [b'0'; 4];
1349        let dyn_array = array.clone_dynamic();
1350        assert_ne!(dyn_array.reflect_type_path(), <[u8; 4]>::type_path());
1351
1352        let map = HashMap::<usize, String>::default();
1353        let dyn_map = map.clone_dynamic();
1354        assert_ne!(
1355            dyn_map.reflect_type_path(),
1356            HashMap::<usize, String>::type_path()
1357        );
1358
1359        let tuple = (0usize, "1".to_string(), 2.0f32);
1360        let mut dyn_tuple = tuple.clone_dynamic();
1361        dyn_tuple.insert::<usize>(3);
1362        assert_ne!(
1363            dyn_tuple.reflect_type_path(),
1364            <(usize, String, f32, usize)>::type_path()
1365        );
1366
1367        #[derive(Reflect)]
1368        struct TestStruct {
1369            a: usize,
1370        }
1371        let struct_ = TestStruct { a: 0 };
1372        let dyn_struct = struct_.clone_dynamic();
1373        assert_ne!(dyn_struct.reflect_type_path(), TestStruct::type_path());
1374
1375        #[derive(Reflect)]
1376        struct TestTupleStruct(usize);
1377        let tuple_struct = TestTupleStruct(0);
1378        let dyn_tuple_struct = tuple_struct.clone_dynamic();
1379        assert_ne!(
1380            dyn_tuple_struct.reflect_type_path(),
1381            TestTupleStruct::type_path()
1382        );
1383    }
1384
1385    macro_rules! assert_type_paths {
1386        ($($ty:ty => $long:literal, $short:literal,)*) => {
1387            $(
1388                assert_eq!(<$ty as TypePath>::type_path(), $long);
1389                assert_eq!(<$ty as TypePath>::short_type_path(), $short);
1390            )*
1391        };
1392    }
1393
1394    #[test]
1395    fn reflect_type_path() {
1396        #[derive(TypePath)]
1397        struct Param;
1398
1399        #[derive(TypePath)]
1400        struct Derive;
1401
1402        #[derive(TypePath)]
1403        #[type_path = "my_alias"]
1404        struct DerivePath;
1405
1406        #[derive(TypePath)]
1407        #[type_path = "my_alias"]
1408        #[type_name = "MyDerivePathName"]
1409        struct DerivePathName;
1410
1411        #[derive(TypePath)]
1412        struct DeriveG<T>(PhantomData<T>);
1413
1414        #[derive(TypePath)]
1415        #[type_path = "my_alias"]
1416        struct DerivePathG<T, const N: usize>(PhantomData<T>);
1417
1418        #[derive(TypePath)]
1419        #[type_path = "my_alias"]
1420        #[type_name = "MyDerivePathNameG"]
1421        struct DerivePathNameG<T>(PhantomData<T>);
1422
1423        struct Macro;
1424        impl_type_path!((in my_alias) Macro);
1425
1426        struct MacroName;
1427        impl_type_path!((in my_alias as MyMacroName) MacroName);
1428
1429        struct MacroG<T, const N: usize>(PhantomData<T>);
1430        impl_type_path!((in my_alias) MacroG<T, const N: usize>);
1431
1432        struct MacroNameG<T>(PhantomData<T>);
1433        impl_type_path!((in my_alias as MyMacroNameG) MacroNameG<T>);
1434
1435        assert_type_paths! {
1436            Derive => "bevy_reflect::tests::Derive", "Derive",
1437            DerivePath => "my_alias::DerivePath", "DerivePath",
1438            DerivePathName => "my_alias::MyDerivePathName", "MyDerivePathName",
1439            DeriveG<Param> => "bevy_reflect::tests::DeriveG<bevy_reflect::tests::Param>", "DeriveG<Param>",
1440            DerivePathG<Param, 10> => "my_alias::DerivePathG<bevy_reflect::tests::Param, 10>", "DerivePathG<Param, 10>",
1441            DerivePathNameG<Param> => "my_alias::MyDerivePathNameG<bevy_reflect::tests::Param>", "MyDerivePathNameG<Param>",
1442            Macro => "my_alias::Macro", "Macro",
1443            MacroName => "my_alias::MyMacroName", "MyMacroName",
1444            MacroG<Param, 10> => "my_alias::MacroG<bevy_reflect::tests::Param, 10>", "MacroG<Param, 10>",
1445            MacroNameG<Param> => "my_alias::MyMacroNameG<bevy_reflect::tests::Param>", "MyMacroNameG<Param>",
1446        }
1447    }
1448
1449    #[test]
1450    fn std_type_paths() {
1451        #[derive(Clone)]
1452        struct Type;
1453
1454        impl TypePath for Type {
1455            fn type_path() -> &'static str {
1456                // for brevity in tests
1457                "Long"
1458            }
1459
1460            fn short_type_path() -> &'static str {
1461                "Short"
1462            }
1463        }
1464
1465        assert_type_paths! {
1466            u8 => "u8", "u8",
1467            Type => "Long", "Short",
1468            &Type => "&Long", "&Short",
1469            [Type] => "[Long]", "[Short]",
1470            &[Type] => "&[Long]", "&[Short]",
1471            [Type; 0] => "[Long; 0]", "[Short; 0]",
1472            [Type; 100] => "[Long; 100]", "[Short; 100]",
1473            () => "()", "()",
1474            (Type,) => "(Long,)", "(Short,)",
1475            (Type, Type) => "(Long, Long)", "(Short, Short)",
1476            (Type, Type, Type) => "(Long, Long, Long)", "(Short, Short, Short)",
1477            Cow<'static, Type> => "alloc::borrow::Cow<Long>", "Cow<Short>",
1478        }
1479    }
1480
1481    #[test]
1482    fn reflect_type_info() {
1483        // TypeInfo
1484        let info = i32::type_info();
1485        assert_eq!(i32::type_path(), info.type_path());
1486        assert_eq!(TypeId::of::<i32>(), info.type_id());
1487
1488        // TypeInfo (unsized)
1489        assert_eq!(
1490            TypeId::of::<dyn Reflect>(),
1491            <dyn Reflect as Typed>::type_info().type_id()
1492        );
1493
1494        // TypeInfo (instance)
1495        let value: &dyn Reflect = &123_i32;
1496        let info = value.get_represented_type_info().unwrap();
1497        assert!(info.is::<i32>());
1498
1499        // Struct
1500        #[derive(Reflect)]
1501        struct MyStruct {
1502            foo: i32,
1503            bar: usize,
1504        }
1505
1506        let info = MyStruct::type_info();
1507        if let TypeInfo::Struct(info) = info {
1508            assert!(info.is::<MyStruct>());
1509            assert_eq!(MyStruct::type_path(), info.type_path());
1510            assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
1511            assert_eq!(TypeId::of::<i32>(), info.field("foo").unwrap().type_id());
1512            assert!(info.field("foo").unwrap().is::<i32>());
1513            assert_eq!("foo", info.field("foo").unwrap().name());
1514            assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
1515        } else {
1516            panic!("Expected `TypeInfo::Struct`");
1517        }
1518
1519        let value: &dyn Reflect = &MyStruct { foo: 123, bar: 321 };
1520        let info = value.get_represented_type_info().unwrap();
1521        assert!(info.is::<MyStruct>());
1522
1523        // Struct (generic)
1524        #[derive(Reflect)]
1525        struct MyGenericStruct<T> {
1526            foo: T,
1527            bar: usize,
1528        }
1529
1530        let info = <MyGenericStruct<i32>>::type_info();
1531        if let TypeInfo::Struct(info) = info {
1532            assert!(info.is::<MyGenericStruct<i32>>());
1533            assert_eq!(MyGenericStruct::<i32>::type_path(), info.type_path());
1534            assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
1535            assert_eq!("foo", info.field("foo").unwrap().name());
1536            assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
1537        } else {
1538            panic!("Expected `TypeInfo::Struct`");
1539        }
1540
1541        let value: &dyn Reflect = &MyGenericStruct {
1542            foo: String::from("Hello!"),
1543            bar: 321,
1544        };
1545        let info = value.get_represented_type_info().unwrap();
1546        assert!(info.is::<MyGenericStruct<String>>());
1547
1548        // Tuple Struct
1549        #[derive(Reflect)]
1550        struct MyTupleStruct(usize, i32, MyStruct);
1551
1552        let info = MyTupleStruct::type_info();
1553        if let TypeInfo::TupleStruct(info) = info {
1554            assert!(info.is::<MyTupleStruct>());
1555            assert_eq!(MyTupleStruct::type_path(), info.type_path());
1556            assert_eq!(i32::type_path(), info.field_at(1).unwrap().type_path());
1557            assert!(info.field_at(1).unwrap().is::<i32>());
1558        } else {
1559            panic!("Expected `TypeInfo::TupleStruct`");
1560        }
1561
1562        // Tuple
1563        type MyTuple = (u32, f32, String);
1564
1565        let info = MyTuple::type_info();
1566        if let TypeInfo::Tuple(info) = info {
1567            assert!(info.is::<MyTuple>());
1568            assert_eq!(MyTuple::type_path(), info.type_path());
1569            assert_eq!(f32::type_path(), info.field_at(1).unwrap().type_path());
1570        } else {
1571            panic!("Expected `TypeInfo::Tuple`");
1572        }
1573
1574        let value: &dyn Reflect = &(123_u32, 1.23_f32, String::from("Hello!"));
1575        let info = value.get_represented_type_info().unwrap();
1576        assert!(info.is::<MyTuple>());
1577
1578        // List
1579        type MyList = Vec<usize>;
1580
1581        let info = MyList::type_info();
1582        if let TypeInfo::List(info) = info {
1583            assert!(info.is::<MyList>());
1584            assert!(info.item_is::<usize>());
1585            assert_eq!(MyList::type_path(), info.type_path());
1586            assert_eq!(usize::type_path(), info.item_type_path_table().path());
1587        } else {
1588            panic!("Expected `TypeInfo::List`");
1589        }
1590
1591        let value: &dyn Reflect = &vec![123_usize];
1592        let info = value.get_represented_type_info().unwrap();
1593        assert!(info.is::<MyList>());
1594
1595        // List (SmallVec)
1596        #[cfg(feature = "smallvec")]
1597        {
1598            type MySmallVec = smallvec::SmallVec<[String; 2]>;
1599
1600            let info = MySmallVec::type_info();
1601            if let TypeInfo::List(info) = info {
1602                assert!(info.is::<MySmallVec>());
1603                assert!(info.item_is::<String>());
1604                assert_eq!(MySmallVec::type_path(), info.type_path());
1605                assert_eq!(String::type_path(), info.item_type_path_table().path());
1606            } else {
1607                panic!("Expected `TypeInfo::List`");
1608            }
1609
1610            let value: MySmallVec = smallvec::smallvec![String::default(); 2];
1611            let value: &dyn Reflect = &value;
1612            let info = value.get_represented_type_info().unwrap();
1613            assert!(info.is::<MySmallVec>());
1614        }
1615
1616        // Array
1617        type MyArray = [usize; 3];
1618
1619        let info = MyArray::type_info();
1620        if let TypeInfo::Array(info) = info {
1621            assert!(info.is::<MyArray>());
1622            assert!(info.item_is::<usize>());
1623            assert_eq!(MyArray::type_path(), info.type_path());
1624            assert_eq!(usize::type_path(), info.item_type_path_table().path());
1625            assert_eq!(3, info.capacity());
1626        } else {
1627            panic!("Expected `TypeInfo::Array`");
1628        }
1629
1630        let value: &dyn Reflect = &[1usize, 2usize, 3usize];
1631        let info = value.get_represented_type_info().unwrap();
1632        assert!(info.is::<MyArray>());
1633
1634        // Cow<'static, str>
1635        type MyCowStr = Cow<'static, str>;
1636
1637        let info = MyCowStr::type_info();
1638        if let TypeInfo::Value(info) = info {
1639            assert!(info.is::<MyCowStr>());
1640            assert_eq!(std::any::type_name::<MyCowStr>(), info.type_path());
1641        } else {
1642            panic!("Expected `TypeInfo::Value`");
1643        }
1644
1645        let value: &dyn Reflect = &Cow::<'static, str>::Owned("Hello!".to_string());
1646        let info = value.get_represented_type_info().unwrap();
1647        assert!(info.is::<MyCowStr>());
1648
1649        // Cow<'static, [u8]>
1650        type MyCowSlice = Cow<'static, [u8]>;
1651
1652        let info = MyCowSlice::type_info();
1653        if let TypeInfo::List(info) = info {
1654            assert!(info.is::<MyCowSlice>());
1655            assert!(info.item_is::<u8>());
1656            assert_eq!(std::any::type_name::<MyCowSlice>(), info.type_path());
1657            assert_eq!(
1658                std::any::type_name::<u8>(),
1659                info.item_type_path_table().path()
1660            );
1661        } else {
1662            panic!("Expected `TypeInfo::List`");
1663        }
1664
1665        let value: &dyn Reflect = &Cow::<'static, [u8]>::Owned(vec![0, 1, 2, 3]);
1666        let info = value.get_represented_type_info().unwrap();
1667        assert!(info.is::<MyCowSlice>());
1668
1669        // Map
1670        type MyMap = HashMap<usize, f32>;
1671
1672        let info = MyMap::type_info();
1673        if let TypeInfo::Map(info) = info {
1674            assert!(info.is::<MyMap>());
1675            assert!(info.key_is::<usize>());
1676            assert!(info.value_is::<f32>());
1677            assert_eq!(MyMap::type_path(), info.type_path());
1678            assert_eq!(usize::type_path(), info.key_type_path_table().path());
1679            assert_eq!(f32::type_path(), info.value_type_path_table().path());
1680        } else {
1681            panic!("Expected `TypeInfo::Map`");
1682        }
1683
1684        let value: &dyn Reflect = &MyMap::new();
1685        let info = value.get_represented_type_info().unwrap();
1686        assert!(info.is::<MyMap>());
1687
1688        // Value
1689        type MyValue = String;
1690
1691        let info = MyValue::type_info();
1692        if let TypeInfo::Value(info) = info {
1693            assert!(info.is::<MyValue>());
1694            assert_eq!(MyValue::type_path(), info.type_path());
1695        } else {
1696            panic!("Expected `TypeInfo::Value`");
1697        }
1698
1699        let value: &dyn Reflect = &String::from("Hello!");
1700        let info = value.get_represented_type_info().unwrap();
1701        assert!(info.is::<MyValue>());
1702    }
1703
1704    #[test]
1705    fn should_permit_higher_ranked_lifetimes() {
1706        #[derive(Reflect)]
1707        #[reflect(from_reflect = false)]
1708        struct TestStruct {
1709            #[reflect(ignore)]
1710            _hrl: for<'a> fn(&'a str) -> &'a str,
1711        }
1712
1713        impl Default for TestStruct {
1714            fn default() -> Self {
1715                TestStruct {
1716                    _hrl: |input| input,
1717                }
1718            }
1719        }
1720
1721        fn get_type_registration<T: GetTypeRegistration>() {}
1722        get_type_registration::<TestStruct>();
1723    }
1724
1725    #[test]
1726    fn should_permit_valid_represented_type_for_dynamic() {
1727        let type_info = <[i32; 2] as Typed>::type_info();
1728        let mut dynamic_array = [123; 2].clone_dynamic();
1729        dynamic_array.set_represented_type(Some(type_info));
1730    }
1731
1732    #[test]
1733    #[should_panic(expected = "expected TypeInfo::Array but received")]
1734    fn should_prohibit_invalid_represented_type_for_dynamic() {
1735        let type_info = <(i32, i32) as Typed>::type_info();
1736        let mut dynamic_array = [123; 2].clone_dynamic();
1737        dynamic_array.set_represented_type(Some(type_info));
1738    }
1739
1740    #[cfg(feature = "documentation")]
1741    mod docstrings {
1742        use super::*;
1743
1744        #[test]
1745        fn should_not_contain_docs() {
1746            // Regular comments do not count as doc comments,
1747            // and are therefore not reflected.
1748            #[derive(Reflect)]
1749            struct SomeStruct;
1750
1751            let info = <SomeStruct as Typed>::type_info();
1752            assert_eq!(None, info.docs());
1753
1754            /*
1755             * Block comments do not count as doc comments,
1756             * and are therefore not reflected.
1757             */
1758            #[derive(Reflect)]
1759            struct SomeOtherStruct;
1760
1761            let info = <SomeOtherStruct as Typed>::type_info();
1762            assert_eq!(None, info.docs());
1763        }
1764
1765        #[test]
1766        fn should_contain_docs() {
1767            /// Some struct.
1768            ///
1769            /// # Example
1770            ///
1771            /// ```ignore (This is only used for a unit test, no need to doc test)
1772            /// let some_struct = SomeStruct;
1773            /// ```
1774            #[derive(Reflect)]
1775            struct SomeStruct;
1776
1777            let info = <SomeStruct as Typed>::type_info();
1778            assert_eq!(
1779                Some(" Some struct.\n\n # Example\n\n ```ignore (This is only used for a unit test, no need to doc test)\n let some_struct = SomeStruct;\n ```"),
1780                info.docs()
1781            );
1782
1783            #[doc = "The compiler automatically converts `///`-style comments into `#[doc]` attributes."]
1784            #[doc = "Of course, you _could_ use the attribute directly if you wanted to."]
1785            #[doc = "Both will be reflected."]
1786            #[derive(Reflect)]
1787            struct SomeOtherStruct;
1788
1789            let info = <SomeOtherStruct as Typed>::type_info();
1790            assert_eq!(
1791                Some("The compiler automatically converts `///`-style comments into `#[doc]` attributes.\nOf course, you _could_ use the attribute directly if you wanted to.\nBoth will be reflected."),
1792                info.docs()
1793            );
1794
1795            /// Some tuple struct.
1796            #[derive(Reflect)]
1797            struct SomeTupleStruct(usize);
1798
1799            let info = <SomeTupleStruct as Typed>::type_info();
1800            assert_eq!(Some(" Some tuple struct."), info.docs());
1801
1802            /// Some enum.
1803            #[derive(Reflect)]
1804            enum SomeEnum {
1805                Foo,
1806            }
1807
1808            let info = <SomeEnum as Typed>::type_info();
1809            assert_eq!(Some(" Some enum."), info.docs());
1810
1811            #[derive(Clone)]
1812            struct SomePrimitive;
1813            impl_reflect_value!(
1814                /// Some primitive for which we have attributed custom documentation.
1815                (in bevy_reflect::tests) SomePrimitive
1816            );
1817
1818            let info = <SomePrimitive as Typed>::type_info();
1819            assert_eq!(
1820                Some(" Some primitive for which we have attributed custom documentation."),
1821                info.docs()
1822            );
1823        }
1824
1825        #[test]
1826        fn fields_should_contain_docs() {
1827            #[derive(Reflect)]
1828            struct SomeStruct {
1829                /// The name
1830                name: String,
1831                /// The index
1832                index: usize,
1833                // Not documented...
1834                data: Vec<i32>,
1835            }
1836
1837            let info = <SomeStruct as Typed>::type_info();
1838            if let TypeInfo::Struct(info) = info {
1839                let mut fields = info.iter();
1840                assert_eq!(Some(" The name"), fields.next().unwrap().docs());
1841                assert_eq!(Some(" The index"), fields.next().unwrap().docs());
1842                assert_eq!(None, fields.next().unwrap().docs());
1843            } else {
1844                panic!("expected struct info");
1845            }
1846        }
1847
1848        #[test]
1849        fn variants_should_contain_docs() {
1850            #[derive(Reflect)]
1851            enum SomeEnum {
1852                // Not documented...
1853                Nothing,
1854                /// Option A
1855                A(
1856                    /// Index
1857                    usize,
1858                ),
1859                /// Option B
1860                B {
1861                    /// Name
1862                    name: String,
1863                },
1864            }
1865
1866            let info = <SomeEnum as Typed>::type_info();
1867            if let TypeInfo::Enum(info) = info {
1868                let mut variants = info.iter();
1869                assert_eq!(None, variants.next().unwrap().docs());
1870
1871                let variant = variants.next().unwrap();
1872                assert_eq!(Some(" Option A"), variant.docs());
1873                if let VariantInfo::Tuple(variant) = variant {
1874                    let field = variant.field_at(0).unwrap();
1875                    assert_eq!(Some(" Index"), field.docs());
1876                } else {
1877                    panic!("expected tuple variant")
1878                }
1879
1880                let variant = variants.next().unwrap();
1881                assert_eq!(Some(" Option B"), variant.docs());
1882                if let VariantInfo::Struct(variant) = variant {
1883                    let field = variant.field_at(0).unwrap();
1884                    assert_eq!(Some(" Name"), field.docs());
1885                } else {
1886                    panic!("expected struct variant")
1887                }
1888            } else {
1889                panic!("expected enum info");
1890            }
1891        }
1892    }
1893
1894    #[test]
1895    fn into_reflect() {
1896        trait TestTrait: Reflect {}
1897
1898        #[derive(Reflect)]
1899        struct TestStruct;
1900
1901        impl TestTrait for TestStruct {}
1902
1903        let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
1904
1905        // Should compile:
1906        let _ = trait_object.into_reflect();
1907    }
1908
1909    #[test]
1910    fn as_reflect() {
1911        trait TestTrait: Reflect {}
1912
1913        #[derive(Reflect)]
1914        struct TestStruct;
1915
1916        impl TestTrait for TestStruct {}
1917
1918        let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
1919
1920        // Should compile:
1921        let _ = trait_object.as_reflect();
1922    }
1923
1924    #[test]
1925    fn should_reflect_debug() {
1926        #[derive(Reflect)]
1927        struct Test {
1928            value: usize,
1929            list: Vec<String>,
1930            array: [f32; 3],
1931            map: HashMap<i32, f32>,
1932            a_struct: SomeStruct,
1933            a_tuple_struct: SomeTupleStruct,
1934            enum_unit: SomeEnum,
1935            enum_tuple: SomeEnum,
1936            enum_struct: SomeEnum,
1937            custom: CustomDebug,
1938            #[reflect(ignore)]
1939            #[allow(dead_code)]
1940            ignored: isize,
1941        }
1942
1943        #[derive(Reflect)]
1944        struct SomeStruct {
1945            foo: String,
1946        }
1947
1948        #[derive(Reflect)]
1949        enum SomeEnum {
1950            A,
1951            B(usize),
1952            C { value: i32 },
1953        }
1954
1955        #[derive(Reflect)]
1956        struct SomeTupleStruct(String);
1957
1958        #[derive(Reflect)]
1959        #[reflect(Debug)]
1960        struct CustomDebug;
1961        impl Debug for CustomDebug {
1962            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1963                f.write_str("Cool debug!")
1964            }
1965        }
1966
1967        let mut map = HashMap::new();
1968        map.insert(123, 1.23);
1969
1970        let test = Test {
1971            value: 123,
1972            list: vec![String::from("A"), String::from("B"), String::from("C")],
1973            array: [1.0, 2.0, 3.0],
1974            map,
1975            a_struct: SomeStruct {
1976                foo: String::from("A Struct!"),
1977            },
1978            a_tuple_struct: SomeTupleStruct(String::from("A Tuple Struct!")),
1979            enum_unit: SomeEnum::A,
1980            enum_tuple: SomeEnum::B(123),
1981            enum_struct: SomeEnum::C { value: 321 },
1982            custom: CustomDebug,
1983            ignored: 321,
1984        };
1985
1986        let reflected: &dyn Reflect = &test;
1987        let expected = r#"
1988bevy_reflect::tests::Test {
1989    value: 123,
1990    list: [
1991        "A",
1992        "B",
1993        "C",
1994    ],
1995    array: [
1996        1.0,
1997        2.0,
1998        3.0,
1999    ],
2000    map: {
2001        123: 1.23,
2002    },
2003    a_struct: bevy_reflect::tests::SomeStruct {
2004        foo: "A Struct!",
2005    },
2006    a_tuple_struct: bevy_reflect::tests::SomeTupleStruct(
2007        "A Tuple Struct!",
2008    ),
2009    enum_unit: A,
2010    enum_tuple: B(
2011        123,
2012    ),
2013    enum_struct: C {
2014        value: 321,
2015    },
2016    custom: Cool debug!,
2017}"#;
2018
2019        assert_eq!(expected, format!("\n{reflected:#?}"));
2020    }
2021
2022    #[test]
2023    fn multiple_reflect_lists() {
2024        #[derive(Hash, PartialEq, Reflect)]
2025        #[reflect(Debug, Hash)]
2026        #[reflect(PartialEq)]
2027        struct Foo(i32);
2028
2029        impl Debug for Foo {
2030            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2031                write!(f, "Foo")
2032            }
2033        }
2034
2035        let foo = Foo(123);
2036        let foo: &dyn Reflect = &foo;
2037
2038        assert!(foo.reflect_hash().is_some());
2039        assert_eq!(Some(true), foo.reflect_partial_eq(foo));
2040        assert_eq!("Foo".to_string(), format!("{foo:?}"));
2041    }
2042
2043    #[test]
2044    fn multiple_reflect_value_lists() {
2045        #[derive(Clone, Hash, PartialEq, Reflect)]
2046        #[reflect_value(Debug, Hash)]
2047        #[reflect_value(PartialEq)]
2048        struct Foo(i32);
2049
2050        impl Debug for Foo {
2051            fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
2052                write!(f, "Foo")
2053            }
2054        }
2055
2056        let foo = Foo(123);
2057        let foo: &dyn Reflect = &foo;
2058
2059        assert!(foo.reflect_hash().is_some());
2060        assert_eq!(Some(true), foo.reflect_partial_eq(foo));
2061        assert_eq!("Foo".to_string(), format!("{foo:?}"));
2062    }
2063
2064    #[test]
2065    fn custom_debug_function() {
2066        #[derive(Reflect)]
2067        #[reflect(Debug(custom_debug))]
2068        struct Foo {
2069            a: u32,
2070        }
2071
2072        fn custom_debug(_x: &Foo, f: &mut Formatter<'_>) -> std::fmt::Result {
2073            write!(f, "123")
2074        }
2075
2076        let foo = Foo { a: 1 };
2077        let foo: &dyn Reflect = &foo;
2078
2079        assert_eq!("123", format!("{:?}", foo));
2080    }
2081
2082    #[test]
2083    fn should_allow_custom_where() {
2084        #[derive(Reflect)]
2085        #[reflect(where T: Default)]
2086        struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
2087
2088        #[derive(Default, TypePath)]
2089        struct Bar;
2090
2091        #[derive(TypePath)]
2092        struct Baz;
2093
2094        assert_impl_all!(Foo<Bar>: Reflect);
2095        assert_not_impl_all!(Foo<Baz>: Reflect);
2096    }
2097
2098    #[test]
2099    fn should_allow_empty_custom_where() {
2100        #[derive(Reflect)]
2101        #[reflect(where)]
2102        struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
2103
2104        #[derive(TypePath)]
2105        struct Bar;
2106
2107        assert_impl_all!(Foo<Bar>: Reflect);
2108    }
2109
2110    #[test]
2111    fn should_allow_multiple_custom_where() {
2112        #[derive(Reflect)]
2113        #[reflect(where T: Default)]
2114        #[reflect(where U: std::ops::Add<T>)]
2115        struct Foo<T, U>(T, U);
2116
2117        #[derive(Reflect)]
2118        struct Baz {
2119            a: Foo<i32, i32>,
2120            b: Foo<u32, u32>,
2121        }
2122
2123        assert_impl_all!(Foo<i32, i32>: Reflect);
2124        assert_not_impl_all!(Foo<i32, usize>: Reflect);
2125    }
2126
2127    #[test]
2128    fn should_allow_custom_where_with_assoc_type() {
2129        trait Trait {
2130            type Assoc;
2131        }
2132
2133        // We don't need `T` to be `Reflect` since we only care about `T::Assoc`
2134        #[derive(Reflect)]
2135        #[reflect(where T::Assoc: core::fmt::Display)]
2136        struct Foo<T: Trait>(T::Assoc);
2137
2138        #[derive(TypePath)]
2139        struct Bar;
2140
2141        impl Trait for Bar {
2142            type Assoc = usize;
2143        }
2144
2145        #[derive(TypePath)]
2146        struct Baz;
2147
2148        impl Trait for Baz {
2149            type Assoc = (f32, f32);
2150        }
2151
2152        assert_impl_all!(Foo<Bar>: Reflect);
2153        assert_not_impl_all!(Foo<Baz>: Reflect);
2154    }
2155
2156    #[test]
2157    fn recursive_typed_storage_does_not_hang() {
2158        #[derive(Reflect)]
2159        struct Recurse<T>(T);
2160
2161        let _ = <Recurse<Recurse<()>> as Typed>::type_info();
2162        let _ = <Recurse<Recurse<()>> as TypePath>::type_path();
2163
2164        #[derive(Reflect)]
2165        #[reflect(no_field_bounds)]
2166        struct SelfRecurse {
2167            recurse: Vec<SelfRecurse>,
2168        }
2169
2170        let _ = <SelfRecurse as Typed>::type_info();
2171        let _ = <SelfRecurse as TypePath>::type_path();
2172
2173        #[derive(Reflect)]
2174        #[reflect(no_field_bounds)]
2175        enum RecurseA {
2176            Recurse(RecurseB),
2177        }
2178
2179        #[derive(Reflect)]
2180        // `#[reflect(no_field_bounds)]` not needed since already added to `RecurseA`
2181        struct RecurseB {
2182            vector: Vec<RecurseA>,
2183        }
2184
2185        let _ = <RecurseA as Typed>::type_info();
2186        let _ = <RecurseA as TypePath>::type_path();
2187        let _ = <RecurseB as Typed>::type_info();
2188        let _ = <RecurseB as TypePath>::type_path();
2189    }
2190
2191    #[test]
2192    fn recursive_registration_does_not_hang() {
2193        #[derive(Reflect)]
2194        struct Recurse<T>(T);
2195
2196        let mut registry = TypeRegistry::empty();
2197
2198        registry.register::<Recurse<Recurse<()>>>();
2199
2200        #[derive(Reflect)]
2201        #[reflect(no_field_bounds)]
2202        struct SelfRecurse {
2203            recurse: Vec<SelfRecurse>,
2204        }
2205
2206        registry.register::<SelfRecurse>();
2207
2208        #[derive(Reflect)]
2209        #[reflect(no_field_bounds)]
2210        enum RecurseA {
2211            Recurse(RecurseB),
2212        }
2213
2214        #[derive(Reflect)]
2215        struct RecurseB {
2216            vector: Vec<RecurseA>,
2217        }
2218
2219        registry.register::<RecurseA>();
2220        assert!(registry.contains(TypeId::of::<RecurseA>()));
2221        assert!(registry.contains(TypeId::of::<RecurseB>()));
2222    }
2223
2224    #[test]
2225    fn can_opt_out_type_path() {
2226        #[derive(Reflect)]
2227        #[reflect(type_path = false)]
2228        struct Foo<T> {
2229            #[reflect(ignore)]
2230            _marker: PhantomData<T>,
2231        }
2232
2233        struct NotTypePath;
2234
2235        impl<T: 'static> TypePath for Foo<T> {
2236            fn type_path() -> &'static str {
2237                std::any::type_name::<Self>()
2238            }
2239
2240            fn short_type_path() -> &'static str {
2241                static CELL: GenericTypePathCell = GenericTypePathCell::new();
2242                CELL.get_or_insert::<Self, _>(|| {
2243                    bevy_utils::get_short_name(std::any::type_name::<Self>())
2244                })
2245            }
2246
2247            fn type_ident() -> Option<&'static str> {
2248                Some("Foo")
2249            }
2250
2251            fn crate_name() -> Option<&'static str> {
2252                Some("bevy_reflect")
2253            }
2254
2255            fn module_path() -> Option<&'static str> {
2256                Some("bevy_reflect::tests")
2257            }
2258        }
2259
2260        // Can use `TypePath`
2261        let path = <Foo<NotTypePath> as TypePath>::type_path();
2262        assert_eq!("bevy_reflect::tests::can_opt_out_type_path::Foo<bevy_reflect::tests::can_opt_out_type_path::NotTypePath>", path);
2263
2264        // Can register the type
2265        let mut registry = TypeRegistry::default();
2266        registry.register::<Foo<NotTypePath>>();
2267
2268        let registration = registry.get(TypeId::of::<Foo<NotTypePath>>()).unwrap();
2269        assert_eq!(
2270            "Foo<NotTypePath>",
2271            registration.type_info().type_path_table().short_path()
2272        );
2273    }
2274
2275    #[test]
2276    fn dynamic_types_debug_format() {
2277        #[derive(Debug, Reflect)]
2278        struct TestTupleStruct(u32);
2279
2280        #[derive(Debug, Reflect)]
2281        enum TestEnum {
2282            A(u32),
2283            B,
2284        }
2285
2286        #[derive(Debug, Reflect)]
2287        // test DynamicStruct
2288        struct TestStruct {
2289            // test DynamicTuple
2290            tuple: (u32, u32),
2291            // test DynamicTupleStruct
2292            tuple_struct: TestTupleStruct,
2293            // test DynamicList
2294            list: Vec<u32>,
2295            // test DynamicArray
2296            array: [u32; 3],
2297            // test DynamicEnum
2298            e: TestEnum,
2299            // test DynamicMap
2300            map: HashMap<u32, u32>,
2301            // test reflected value
2302            value: u32,
2303        }
2304        let mut map = HashMap::new();
2305        map.insert(9, 10);
2306        let mut test_struct = TestStruct {
2307            tuple: (0, 1),
2308            list: vec![2, 3, 4],
2309            array: [5, 6, 7],
2310            tuple_struct: TestTupleStruct(8),
2311            e: TestEnum::A(11),
2312            map,
2313            value: 12,
2314        }
2315        .clone_value();
2316        let test_struct = test_struct.downcast_mut::<DynamicStruct>().unwrap();
2317
2318        // test unknown DynamicStruct
2319        let mut test_unknown_struct = DynamicStruct::default();
2320        test_unknown_struct.insert("a", 13);
2321        test_struct.insert("unknown_struct", test_unknown_struct);
2322        // test unknown DynamicTupleStruct
2323        let mut test_unknown_tuple_struct = DynamicTupleStruct::default();
2324        test_unknown_tuple_struct.insert(14);
2325        test_struct.insert("unknown_tuplestruct", test_unknown_tuple_struct);
2326        assert_eq!(
2327            format!("{:?}", test_struct),
2328            "DynamicStruct(bevy_reflect::tests::TestStruct { \
2329                tuple: DynamicTuple((0, 1)), \
2330                tuple_struct: DynamicTupleStruct(bevy_reflect::tests::TestTupleStruct(8)), \
2331                list: DynamicList([2, 3, 4]), \
2332                array: DynamicArray([5, 6, 7]), \
2333                e: DynamicEnum(A(11)), \
2334                map: DynamicMap({9: 10}), \
2335                value: 12, \
2336                unknown_struct: DynamicStruct(_ { a: 13 }), \
2337                unknown_tuplestruct: DynamicTupleStruct(_(14)) \
2338            })"
2339        );
2340    }
2341
2342    #[test]
2343    fn assert_impl_reflect_macro_on_all() {
2344        struct Struct {
2345            foo: (),
2346        }
2347        struct TupleStruct(());
2348        enum Enum {
2349            Foo { foo: () },
2350            Bar(()),
2351        }
2352
2353        impl_reflect!(
2354            #[type_path = "my_crate::foo"]
2355            struct Struct {
2356                foo: (),
2357            }
2358        );
2359
2360        impl_reflect!(
2361            #[type_path = "my_crate::foo"]
2362            struct TupleStruct(());
2363        );
2364
2365        impl_reflect!(
2366            #[type_path = "my_crate::foo"]
2367            enum Enum {
2368                Foo { foo: () },
2369                Bar(()),
2370            }
2371        );
2372
2373        assert_impl_all!(Struct: Reflect);
2374        assert_impl_all!(TupleStruct: Reflect);
2375        assert_impl_all!(Enum: Reflect);
2376    }
2377
2378    #[cfg(feature = "glam")]
2379    mod glam {
2380        use super::*;
2381        use ::glam::{quat, vec3, Quat, Vec3};
2382
2383        #[test]
2384        fn quat_serialization() {
2385            let q = quat(1.0, 2.0, 3.0, 4.0);
2386
2387            let mut registry = TypeRegistry::default();
2388            registry.register::<f32>();
2389            registry.register::<Quat>();
2390
2391            let ser = ReflectSerializer::new(&q, &registry);
2392
2393            let config = PrettyConfig::default()
2394                .new_line(String::from("\n"))
2395                .indentor(String::from("    "));
2396            let output = to_string_pretty(&ser, config).unwrap();
2397            let expected = r#"
2398{
2399    "glam::Quat": (
2400        x: 1.0,
2401        y: 2.0,
2402        z: 3.0,
2403        w: 4.0,
2404    ),
2405}"#;
2406
2407            assert_eq!(expected, format!("\n{output}"));
2408        }
2409
2410        #[test]
2411        fn quat_deserialization() {
2412            let data = r#"
2413{
2414    "glam::Quat": (
2415        x: 1.0,
2416        y: 2.0,
2417        z: 3.0,
2418        w: 4.0,
2419    ),
2420}"#;
2421
2422            let mut registry = TypeRegistry::default();
2423            registry.register::<Quat>();
2424            registry.register::<f32>();
2425
2426            let de = ReflectDeserializer::new(&registry);
2427
2428            let mut deserializer =
2429                Deserializer::from_str(data).expect("Failed to acquire deserializer");
2430
2431            let dynamic_struct = de
2432                .deserialize(&mut deserializer)
2433                .expect("Failed to deserialize");
2434
2435            let mut result = Quat::default();
2436
2437            result.apply(&*dynamic_struct);
2438
2439            assert_eq!(result, quat(1.0, 2.0, 3.0, 4.0));
2440        }
2441
2442        #[test]
2443        fn vec3_serialization() {
2444            let v = vec3(12.0, 3.0, -6.9);
2445
2446            let mut registry = TypeRegistry::default();
2447            registry.register::<f32>();
2448            registry.register::<Vec3>();
2449
2450            let ser = ReflectSerializer::new(&v, &registry);
2451
2452            let config = PrettyConfig::default()
2453                .new_line(String::from("\n"))
2454                .indentor(String::from("    "));
2455            let output = to_string_pretty(&ser, config).unwrap();
2456            let expected = r#"
2457{
2458    "glam::Vec3": (
2459        x: 12.0,
2460        y: 3.0,
2461        z: -6.9,
2462    ),
2463}"#;
2464
2465            assert_eq!(expected, format!("\n{output}"));
2466        }
2467
2468        #[test]
2469        fn vec3_deserialization() {
2470            let data = r#"
2471{
2472    "glam::Vec3": (
2473        x: 12.0,
2474        y: 3.0,
2475        z: -6.9,
2476    ),
2477}"#;
2478
2479            let mut registry = TypeRegistry::default();
2480            registry.add_registration(Vec3::get_type_registration());
2481            registry.add_registration(f32::get_type_registration());
2482
2483            let de = ReflectDeserializer::new(&registry);
2484
2485            let mut deserializer =
2486                Deserializer::from_str(data).expect("Failed to acquire deserializer");
2487
2488            let dynamic_struct = de
2489                .deserialize(&mut deserializer)
2490                .expect("Failed to deserialize");
2491
2492            let mut result = Vec3::default();
2493
2494            result.apply(&*dynamic_struct);
2495
2496            assert_eq!(result, vec3(12.0, 3.0, -6.9));
2497        }
2498
2499        #[test]
2500        fn vec3_field_access() {
2501            let mut v = vec3(1.0, 2.0, 3.0);
2502
2503            assert_eq!(*v.get_field::<f32>("x").unwrap(), 1.0);
2504
2505            *v.get_field_mut::<f32>("y").unwrap() = 6.0;
2506
2507            assert_eq!(v.y, 6.0);
2508        }
2509
2510        #[test]
2511        fn vec3_path_access() {
2512            let mut v = vec3(1.0, 2.0, 3.0);
2513
2514            assert_eq!(
2515                *v.reflect_path("x").unwrap().downcast_ref::<f32>().unwrap(),
2516                1.0
2517            );
2518
2519            *v.reflect_path_mut("y")
2520                .unwrap()
2521                .downcast_mut::<f32>()
2522                .unwrap() = 6.0;
2523
2524            assert_eq!(v.y, 6.0);
2525        }
2526
2527        #[test]
2528        fn vec3_apply_dynamic() {
2529            let mut v = vec3(3.0, 3.0, 3.0);
2530
2531            let mut d = DynamicStruct::default();
2532            d.insert("x", 4.0f32);
2533            d.insert("y", 2.0f32);
2534            d.insert("z", 1.0f32);
2535
2536            v.apply(&d);
2537
2538            assert_eq!(v, vec3(4.0, 2.0, 1.0));
2539        }
2540    }
2541}