bevy_reflect/
lib.rs

1#![cfg_attr(
2    any(docsrs, docsrs_dep),
3    expect(
4        internal_features,
5        reason = "rustdoc_internals is needed for fake_variadic"
6    )
7)]
8#![cfg_attr(any(docsrs, docsrs_dep), feature(doc_cfg, rustdoc_internals))]
9#![doc(
10    html_logo_url = "https://bevy.org/assets/icon.png",
11    html_favicon_url = "https://bevy.org/assets/icon.png"
12)]
13
14//! Reflection in Rust.
15//!
16//! [Reflection] is a powerful tool provided within many programming languages
17//! that allows for meta-programming: using information _about_ the program to
18//! _affect_ the program.
19//! In other words, reflection allows us to inspect the program itself, its
20//! syntax, and its type information at runtime.
21//!
22//! This crate adds this missing reflection functionality to Rust.
23//! Though it was made with the [Bevy] game engine in mind,
24//! it's a general-purpose solution that can be used in any Rust project.
25//!
26//! At a very high level, this crate allows you to:
27//! * Dynamically interact with Rust values
28//! * Access type metadata at runtime
29//! * Serialize and deserialize (i.e. save and load) data
30//!
31//! It's important to note that because of missing features in Rust,
32//! there are some [limitations] with this crate.
33//!
34//! # The `Reflect` and `PartialReflect` traits
35//!
36//! At the root of [`bevy_reflect`] is the [`PartialReflect`] trait.
37//!
38//! Its purpose is to allow dynamic [introspection] of values,
39//! following Rust's type system through a system of [subtraits].
40//!
41//! Its primary purpose is to allow all implementors to be passed around
42//! as a `dyn PartialReflect` trait object in one of the following forms:
43//! * `&dyn PartialReflect`
44//! * `&mut dyn PartialReflect`
45//! * `Box<dyn PartialReflect>`
46//!
47//! This allows values of types implementing `PartialReflect`
48//! to be operated upon completely dynamically (at a small [runtime cost]).
49//!
50//! Building on `PartialReflect` is the [`Reflect`] trait.
51//!
52//! `PartialReflect` is a supertrait of `Reflect`
53//! so any type implementing `Reflect` implements `PartialReflect` by definition.
54//! `dyn Reflect` trait objects can be used similarly to `dyn PartialReflect`,
55//! but `Reflect` is also often used in trait bounds (like `T: Reflect`).
56//!
57//! The distinction between `PartialReflect` and `Reflect` is summarized in the following:
58//! * `PartialReflect` is a trait for interacting with values under `bevy_reflect`'s data model.
59//!   This means values implementing `PartialReflect` can be dynamically constructed and introspected.
60//! * The `Reflect` trait, however, ensures that the interface exposed by `PartialReflect`
61//!   on types which additionally implement `Reflect` mirrors the structure of a single Rust type.
62//! * This means `dyn Reflect` trait objects can be directly downcast to concrete types,
63//!   where `dyn PartialReflect` trait object cannot.
64//! * `Reflect`, since it provides a stronger type-correctness guarantee,
65//!   is the trait used to interact with [the type registry].
66//!
67//! ## Converting between `PartialReflect` and `Reflect`
68//!
69//! Since `T: Reflect` implies `T: PartialReflect`, conversion from a `dyn Reflect` to a `dyn PartialReflect`
70//! trait object (upcasting) is infallible and can be performed with one of the following methods.
71//! Note that these are temporary while [the language feature for dyn upcasting coercion] is experimental:
72//! * [`PartialReflect::as_partial_reflect`] for `&dyn PartialReflect`
73//! * [`PartialReflect::as_partial_reflect_mut`] for `&mut dyn PartialReflect`
74//! * [`PartialReflect::into_partial_reflect`] for `Box<dyn PartialReflect>`
75//!
76//! For conversion in the other direction — downcasting `dyn PartialReflect` to `dyn Reflect` —
77//! there are fallible methods:
78//! * [`PartialReflect::try_as_reflect`] for `&dyn Reflect`
79//! * [`PartialReflect::try_as_reflect_mut`] for `&mut dyn Reflect`
80//! * [`PartialReflect::try_into_reflect`] for `Box<dyn Reflect>`
81//!
82//! Additionally, [`FromReflect::from_reflect`] can be used to convert a `dyn PartialReflect` to a concrete type
83//! which implements `Reflect`.
84//!
85//! # Implementing `Reflect`
86//!
87//! Implementing `Reflect` (and `PartialReflect`) is easily done using the provided [derive macro]:
88//!
89//! ```
90//! # use bevy_reflect::Reflect;
91//! #[derive(Reflect)]
92//! struct MyStruct {
93//!   foo: i32
94//! }
95//! ```
96//!
97//! This will automatically generate the implementation of `Reflect` for any struct or enum.
98//!
99//! It will also generate other very important trait implementations used for reflection:
100//! * [`GetTypeRegistration`]
101//! * [`Typed`]
102//! * [`Struct`], [`TupleStruct`], or [`Enum`] depending on the type
103//!
104//! ## Requirements
105//!
106//! We can implement `Reflect` on any type that satisfies _both_ of the following conditions:
107//! * The type implements `Any`, `Send`, and `Sync`.
108//!   For the `Any` requirement to be satisfied, the type itself must have a [`'static` lifetime].
109//! * All fields and sub-elements themselves implement `Reflect`
110//!   (see the [derive macro documentation] for details on how to ignore certain fields when deriving).
111//!
112//! Additionally, using the derive macro on enums requires a third condition to be met:
113//! * All fields and sub-elements must implement [`FromReflect`]—
114//!   another important reflection trait discussed in a later section.
115//!
116//! # The Reflection Subtraits
117//!
118//! Since [`PartialReflect`] is meant to cover any and every type, this crate also comes with a few
119//! more traits to accompany `PartialReflect` and provide more specific interactions.
120//! We refer to these traits as the _reflection subtraits_ since they all have `PartialReflect` as a supertrait.
121//! The current list of reflection subtraits include:
122//! * [`Tuple`]
123//! * [`Array`]
124//! * [`List`]
125//! * [`Set`]
126//! * [`Map`]
127//! * [`Struct`]
128//! * [`TupleStruct`]
129//! * [`Enum`]
130//! * [`Function`] (requires the `functions` feature)
131//!
132//! As mentioned previously, the last three are automatically implemented by the [derive macro].
133//!
134//! Each of these traits come with their own methods specific to their respective category.
135//! For example, we can access our struct's fields by name using the [`Struct::field`] method.
136//!
137//! ```
138//! # use bevy_reflect::{PartialReflect, Reflect, Struct};
139//! # #[derive(Reflect)]
140//! # struct MyStruct {
141//! #   foo: i32
142//! # }
143//! let my_struct: Box<dyn Struct> = Box::new(MyStruct {
144//!   foo: 123
145//! });
146//! let foo: &dyn PartialReflect = my_struct.field("foo").unwrap();
147//! assert_eq!(Some(&123), foo.try_downcast_ref::<i32>());
148//! ```
149//!
150//! Since most data is passed around as `dyn PartialReflect` or `dyn Reflect` trait objects,
151//! the `PartialReflect` trait has methods for going to and from these subtraits.
152//!
153//! [`PartialReflect::reflect_kind`], [`PartialReflect::reflect_ref`],
154//! [`PartialReflect::reflect_mut`], and [`PartialReflect::reflect_owned`] all return
155//! an enum that respectively contains zero-sized, immutable, mutable, and owned access to the type as a subtrait object.
156//!
157//! For example, we can get out a `dyn Tuple` from our reflected tuple type using one of these methods.
158//!
159//! ```
160//! # use bevy_reflect::{PartialReflect, ReflectRef};
161//! let my_tuple: Box<dyn PartialReflect> = Box::new((1, 2, 3));
162//! let my_tuple = my_tuple.reflect_ref().as_tuple().unwrap();
163//! assert_eq!(3, my_tuple.field_len());
164//! ```
165//!
166//! And to go back to a general-purpose `dyn PartialReflect`,
167//! we can just use the matching [`PartialReflect::as_partial_reflect`], [`PartialReflect::as_partial_reflect_mut`],
168//! or [`PartialReflect::into_partial_reflect`] methods.
169//!
170//! ## Opaque Types
171//!
172//! Some types don't fall under a particular subtrait.
173//!
174//! These types hide their internal structure to reflection,
175//! either because it is not possible, difficult, or not useful to reflect its internals.
176//! Such types are known as _opaque_ types.
177//!
178//! This includes truly opaque types like `String` or `Instant`,
179//! but also includes all the primitive types (e.g.  `bool`, `usize`, etc.)
180//! since they can't be broken down any further.
181//!
182//! # Dynamic Types
183//!
184//! Each subtrait comes with a corresponding _dynamic_ type.
185//!
186//! The available dynamic types are:
187//! * [`DynamicTuple`]
188//! * [`DynamicArray`]
189//! * [`DynamicList`]
190//! * [`DynamicMap`]
191//! * [`DynamicStruct`]
192//! * [`DynamicTupleStruct`]
193//! * [`DynamicEnum`]
194//!
195//! These dynamic types may contain any arbitrary reflected data.
196//!
197//! ```
198//! # use bevy_reflect::{DynamicStruct, Struct};
199//! let mut data = DynamicStruct::default();
200//! data.insert("foo", 123_i32);
201//! assert_eq!(Some(&123), data.field("foo").unwrap().try_downcast_ref::<i32>())
202//! ```
203//!
204//! They are most commonly used as "proxies" for other types,
205//! where they contain the same data as— and therefore, represent— a concrete type.
206//! The [`PartialReflect::to_dynamic`] method will return a dynamic type for all non-opaque types,
207//! allowing all types to essentially be "cloned" into a dynamic type.
208//! And since dynamic types themselves implement [`PartialReflect`],
209//! we may pass them around just like most other reflected types.
210//!
211//! ```
212//! # use bevy_reflect::{DynamicStruct, PartialReflect, Reflect};
213//! # #[derive(Reflect)]
214//! # struct MyStruct {
215//! #   foo: i32
216//! # }
217//! let original: Box<dyn Reflect> = Box::new(MyStruct {
218//!   foo: 123
219//! });
220//!
221//! // `dynamic` will be a `DynamicStruct` representing a `MyStruct`
222//! let dynamic: Box<dyn PartialReflect> = original.to_dynamic();
223//! assert!(dynamic.represents::<MyStruct>());
224//! ```
225//!
226//! ## Patching
227//!
228//! These dynamic types come in handy when needing to apply multiple changes to another type.
229//! This is known as "patching" and is done using the [`PartialReflect::apply`] and [`PartialReflect::try_apply`] methods.
230//!
231//! ```
232//! # use bevy_reflect::{DynamicEnum, PartialReflect};
233//! let mut value = Some(123_i32);
234//! let patch = DynamicEnum::new("None", ());
235//! value.apply(&patch);
236//! assert_eq!(None, value);
237//! ```
238//!
239//! ## `FromReflect`
240//!
241//! It's important to remember that dynamic types are _not_ the concrete type they may be representing.
242//! A common mistake is to treat them like such when trying to cast back to the original type
243//! or when trying to make use of a reflected trait which expects the actual type.
244//!
245//! ```should_panic
246//! # use bevy_reflect::{DynamicStruct, PartialReflect, Reflect};
247//! # #[derive(Reflect)]
248//! # struct MyStruct {
249//! #   foo: i32
250//! # }
251//! let original: Box<dyn Reflect> = Box::new(MyStruct {
252//!   foo: 123
253//! });
254//!
255//! let dynamic: Box<dyn PartialReflect> = original.to_dynamic();
256//! let value = dynamic.try_take::<MyStruct>().unwrap(); // PANIC!
257//! ```
258//!
259//! To resolve this issue, we'll need to convert the dynamic type to the concrete one.
260//! This is where [`FromReflect`] comes in.
261//!
262//! `FromReflect` is a trait that allows an instance of a type to be generated from a
263//! dynamic representation— even partial ones.
264//! And since the [`FromReflect::from_reflect`] method takes the data by reference,
265//! this can be used to effectively clone data (to an extent).
266//!
267//! It is automatically implemented when [deriving `Reflect`] on a type unless opted out of
268//! using `#[reflect(from_reflect = false)]` on the item.
269//!
270//! ```
271//! # use bevy_reflect::{FromReflect, PartialReflect, Reflect};
272//! #[derive(Reflect)]
273//! struct MyStruct {
274//!   foo: i32
275//! }
276//! let original: Box<dyn Reflect> = Box::new(MyStruct {
277//!   foo: 123
278//! });
279//!
280//! let dynamic: Box<dyn PartialReflect> = original.to_dynamic();
281//! let value = <MyStruct as FromReflect>::from_reflect(&*dynamic).unwrap(); // OK!
282//! ```
283//!
284//! When deriving, all active fields and sub-elements must also implement `FromReflect`.
285//!
286//! Fields can be given default values for when a field is missing in the passed value or even ignored.
287//! Ignored fields must either implement [`Default`] or have a default function specified
288//! using `#[reflect(default = "path::to::function")]`.
289//!
290//! See the [derive macro documentation](derive@crate::FromReflect) for details.
291//!
292//! All primitives and simple types implement `FromReflect` by relying on their [`Default`] implementation.
293//!
294//! # Path navigation
295//!
296//! The [`GetPath`] trait allows accessing arbitrary nested fields of an [`PartialReflect`] type.
297//!
298//! Using `GetPath`, it is possible to use a path string to access a specific field
299//! of a reflected type.
300//!
301//! ```
302//! # use bevy_reflect::{Reflect, GetPath};
303//! #[derive(Reflect)]
304//! struct MyStruct {
305//!   value: Vec<Option<u32>>
306//! }
307//!
308//! let my_struct = MyStruct {
309//!   value: vec![None, None, Some(123)],
310//! };
311//! assert_eq!(
312//!   my_struct.path::<u32>(".value[2].0").unwrap(),
313//!   &123,
314//! );
315//! ```
316//!
317//! # Type Registration
318//!
319//! This crate also comes with a [`TypeRegistry`] that can be used to store and retrieve additional type metadata at runtime,
320//! such as helper types and trait implementations.
321//!
322//! The [derive macro] for [`Reflect`] also generates an implementation of the [`GetTypeRegistration`] trait,
323//! which is used by the registry to generate a [`TypeRegistration`] struct for that type.
324//! We can then register additional [type data] we want associated with that type.
325//!
326//! For example, we can register [`ReflectDefault`] on our type so that its `Default` implementation
327//! may be used dynamically.
328//!
329//! ```
330//! # use bevy_reflect::{Reflect, TypeRegistry, prelude::ReflectDefault};
331//! #[derive(Reflect, Default)]
332//! struct MyStruct {
333//!   foo: i32
334//! }
335//! let mut registry = TypeRegistry::empty();
336//! registry.register::<MyStruct>();
337//! registry.register_type_data::<MyStruct, ReflectDefault>();
338//!
339//! let registration = registry.get(core::any::TypeId::of::<MyStruct>()).unwrap();
340//! let reflect_default = registration.data::<ReflectDefault>().unwrap();
341//!
342//! let new_value: Box<dyn Reflect> = reflect_default.default();
343//! assert!(new_value.is::<MyStruct>());
344//! ```
345//!
346//! Because this operation is so common, the derive macro actually has a shorthand for it.
347//! By using the `#[reflect(Trait)]` attribute, the derive macro will automatically register a matching,
348//! in-scope `ReflectTrait` type within the `GetTypeRegistration` implementation.
349//!
350//! ```
351//! use bevy_reflect::prelude::{Reflect, ReflectDefault};
352//!
353//! #[derive(Reflect, Default)]
354//! #[reflect(Default)]
355//! struct MyStruct {
356//!   foo: i32
357//! }
358//! ```
359//!
360//! ## Reflecting Traits
361//!
362//! Type data doesn't have to be tied to a trait, but it's often extremely useful to create trait type data.
363//! These allow traits to be used directly on a `dyn Reflect` (and not a `dyn PartialReflect`)
364//! while utilizing the underlying type's implementation.
365//!
366//! For any [object-safe] trait, we can easily generate a corresponding `ReflectTrait` type for our trait
367//! using the [`#[reflect_trait]`](reflect_trait) macro.
368//!
369//! ```
370//! # use bevy_reflect::{Reflect, reflect_trait, TypeRegistry};
371//! #[reflect_trait] // Generates a `ReflectMyTrait` type
372//! pub trait MyTrait {}
373//! impl<T: Reflect> MyTrait for T {}
374//!
375//! let mut registry = TypeRegistry::new();
376//! registry.register_type_data::<i32, ReflectMyTrait>();
377//! ```
378//!
379//! The generated type data can be used to convert a valid `dyn Reflect` into a `dyn MyTrait`.
380//! See the [dynamic types example](https://github.com/bevyengine/bevy/blob/latest/examples/reflection/dynamic_types.rs)
381//! for more information and usage details.
382//!
383//! # Serialization
384//!
385//! By using reflection, we are also able to get serialization capabilities for free.
386//! In fact, using [`bevy_reflect`] can result in faster compile times and reduced code generation over
387//! directly deriving the [`serde`] traits.
388//!
389//! The way it works is by moving the serialization logic into common serializers and deserializers:
390//! * [`ReflectSerializer`]
391//! * [`TypedReflectSerializer`]
392//! * [`ReflectDeserializer`]
393//! * [`TypedReflectDeserializer`]
394//!
395//! All of these structs require a reference to the [registry] so that [type information] can be retrieved,
396//! as well as registered type data, such as [`ReflectSerialize`] and [`ReflectDeserialize`].
397//!
398//! The general entry point are the "untyped" versions of these structs.
399//! These will automatically extract the type information and pass them into their respective "typed" version.
400//!
401//! The output of the `ReflectSerializer` will be a map, where the key is the [type path]
402//! and the value is the serialized data.
403//! The `TypedReflectSerializer` will simply output the serialized data.
404//!
405//! The `ReflectDeserializer` can be used to deserialize this map and return a `Box<dyn Reflect>`,
406//! where the underlying type will be a dynamic type representing some concrete type (except for opaque types).
407//!
408//! Again, it's important to remember that dynamic types may need to be converted to their concrete counterparts
409//! in order to be used in certain cases.
410//! This can be achieved using [`FromReflect`].
411//!
412//! ```
413//! # use serde::de::DeserializeSeed;
414//! # use bevy_reflect::{
415//! #     serde::{ReflectSerializer, ReflectDeserializer},
416//! #     Reflect, PartialReflect, FromReflect, TypeRegistry
417//! # };
418//! #[derive(Reflect, PartialEq, Debug)]
419//! struct MyStruct {
420//!   foo: i32
421//! }
422//!
423//! let original_value = MyStruct {
424//!   foo: 123
425//! };
426//!
427//! // Register
428//! let mut registry = TypeRegistry::new();
429//! registry.register::<MyStruct>();
430//!
431//! // Serialize
432//! let reflect_serializer = ReflectSerializer::new(original_value.as_partial_reflect(), &registry);
433//! let serialized_value: String = ron::to_string(&reflect_serializer).unwrap();
434//!
435//! // Deserialize
436//! let reflect_deserializer = ReflectDeserializer::new(&registry);
437//! let deserialized_value: Box<dyn PartialReflect> = reflect_deserializer.deserialize(
438//!   &mut ron::Deserializer::from_str(&serialized_value).unwrap()
439//! ).unwrap();
440//!
441//! // Convert
442//! let converted_value = <MyStruct as FromReflect>::from_reflect(&*deserialized_value).unwrap();
443//!
444//! assert_eq!(original_value, converted_value);
445//! ```
446//!
447//! # Limitations
448//!
449//! While this crate offers a lot in terms of adding reflection to Rust,
450//! it does come with some limitations that don't make it as featureful as reflection
451//! in other programming languages.
452//!
453//! ## Non-Static Lifetimes
454//!
455//! One of the most obvious limitations is the `'static` requirement.
456//! Rust requires fields to define a lifetime for referenced data,
457//! but [`Reflect`] requires all types to have a `'static` lifetime.
458//! This makes it impossible to reflect any type with non-static borrowed data.
459//!
460//! ## Generic Function Reflection
461//!
462//! Another limitation is the inability to reflect over generic functions directly. It can be done, but will
463//! typically require manual monomorphization (i.e. manually specifying the types the generic method can
464//! take).
465//!
466//! # Features
467//!
468//! ## `bevy`
469//!
470//! | Default | Dependencies                              |
471//! | :-----: | :---------------------------------------: |
472//! | ❌      | [`bevy_math`], [`glam`], [`smallvec`]     |
473//!
474//! This feature makes it so that the appropriate reflection traits are implemented on all the types
475//! necessary for the [Bevy] game engine.
476//! enables the optional dependencies: [`bevy_math`], [`glam`], and [`smallvec`].
477//! These dependencies are used by the [Bevy] game engine and must define their reflection implementations
478//! within this crate due to Rust's [orphan rule].
479//!
480//! ## `functions`
481//!
482//! | Default | Dependencies                      |
483//! | :-----: | :-------------------------------: |
484//! | ❌      | [`bevy_reflect_derive/functions`] |
485//!
486//! This feature allows creating a [`DynamicFunction`] or [`DynamicFunctionMut`] from Rust functions. Dynamic
487//! functions can then be called with valid [`ArgList`]s.
488//!
489//! For more information, read the [`func`] module docs.
490//!
491//! ## `documentation`
492//!
493//! | Default | Dependencies                                  |
494//! | :-----: | :-------------------------------------------: |
495//! | ❌      | [`bevy_reflect_derive/documentation`]         |
496//!
497//! This feature enables capturing doc comments as strings for items that [derive `Reflect`].
498//! Documentation information can then be accessed at runtime on the [`TypeInfo`] of that item.
499//!
500//! This can be useful for generating documentation for scripting language interop or
501//! for displaying tooltips in an editor.
502//!
503//! ## `debug`
504//!
505//! | Default | Dependencies                                  |
506//! | :-----: | :-------------------------------------------: |
507//! | ✅      | `debug_stack`                                 |
508//!
509//! This feature enables useful debug features for reflection.
510//!
511//! This includes the `debug_stack` feature,
512//! which enables capturing the type stack when serializing or deserializing a type
513//! and displaying it in error messages.
514//!
515//! ## `auto_register_inventory`/`auto_register_static`
516//!
517//! | Default | Dependencies                      |
518//! | :-----: | :-------------------------------: |
519//! | ✅      | `bevy_reflect_derive/auto_register_inventory` |
520//! | ❌      | `bevy_reflect_derive/auto_register_static` |
521//!
522//! These features enable automatic registration of types that derive [`Reflect`].
523//!
524//! - `auto_register_inventory` uses `inventory` to collect types on supported platforms (Linux, macOS, iOS, FreeBSD, Android, Windows, WebAssembly).
525//! - `auto_register_static` uses platform-independent way to collect types, but requires additional setup and might
526//!   slow down compilation, so it should only be used on platforms not supported by `inventory`.
527//!   See documentation for [`load_type_registrations`] macro for more info
528//!
529//! When this feature is enabled `bevy_reflect` will automatically collects all types that derive [`Reflect`] on app startup,
530//! and [`TypeRegistry::register_derived_types`] can be used to register these types at any point in the program.
531//! However, this does not apply to types with generics: their desired monomorphized representations must be registered manually.
532//!
533//! [Reflection]: https://en.wikipedia.org/wiki/Reflective_programming
534//! [Bevy]: https://bevy.org/
535//! [limitations]: #limitations
536//! [`bevy_reflect`]: crate
537//! [introspection]: https://en.wikipedia.org/wiki/Type_introspection
538//! [subtraits]: #the-reflection-subtraits
539//! [the type registry]: #type-registration
540//! [runtime cost]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch
541//! [the language feature for dyn upcasting coercion]: https://github.com/rust-lang/rust/issues/65991
542//! [derive macro]: derive@crate::Reflect
543//! [`'static` lifetime]: https://doc.rust-lang.org/rust-by-example/scope/lifetime/static_lifetime.html#trait-bound
544//! [`Function`]: crate::func::Function
545//! [derive macro documentation]: derive@crate::Reflect
546//! [deriving `Reflect`]: derive@crate::Reflect
547//! [type data]: TypeData
548//! [`ReflectDefault`]: std_traits::ReflectDefault
549//! [object-safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety
550//! [`serde`]: ::serde
551//! [`ReflectSerializer`]: serde::ReflectSerializer
552//! [`TypedReflectSerializer`]: serde::TypedReflectSerializer
553//! [`ReflectDeserializer`]: serde::ReflectDeserializer
554//! [`TypedReflectDeserializer`]: serde::TypedReflectDeserializer
555//! [registry]: TypeRegistry
556//! [type information]: TypeInfo
557//! [type path]: TypePath
558//! [type registry]: TypeRegistry
559//! [`bevy_math`]: https://docs.rs/bevy_math/latest/bevy_math/
560//! [`glam`]: https://docs.rs/glam/latest/glam/
561//! [`smallvec`]: https://docs.rs/smallvec/latest/smallvec/
562//! [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.
563//! [`bevy_reflect_derive/documentation`]: bevy_reflect_derive
564//! [`bevy_reflect_derive/functions`]: bevy_reflect_derive
565//! [`DynamicFunction`]: crate::func::DynamicFunction
566//! [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut
567//! [`ArgList`]: crate::func::ArgList
568//! [derive `Reflect`]: derive@crate::Reflect
569
570#![no_std]
571
572#[cfg(feature = "std")]
573extern crate std;
574
575extern crate alloc;
576
577// Required to make proc macros work in bevy itself.
578extern crate self as bevy_reflect;
579
580mod array;
581mod error;
582mod fields;
583mod from_reflect;
584#[cfg(feature = "functions")]
585pub mod func;
586mod is;
587mod kind;
588mod list;
589mod map;
590mod path;
591mod reflect;
592mod reflectable;
593mod remote;
594mod set;
595mod struct_trait;
596mod tuple;
597mod tuple_struct;
598mod type_info;
599mod type_path;
600mod type_registry;
601
602mod impls {
603    mod alloc;
604    mod bevy_platform;
605    mod core;
606    mod foldhash;
607    #[cfg(feature = "hashbrown")]
608    mod hashbrown;
609    mod macros;
610    #[cfg(feature = "std")]
611    mod std;
612
613    #[cfg(feature = "glam")]
614    mod glam;
615    #[cfg(feature = "petgraph")]
616    mod petgraph;
617    #[cfg(feature = "smallvec")]
618    mod smallvec;
619    #[cfg(feature = "smol_str")]
620    mod smol_str;
621    #[cfg(feature = "uuid")]
622    mod uuid;
623    #[cfg(feature = "wgpu-types")]
624    mod wgpu_types;
625}
626
627pub mod attributes;
628mod enums;
629mod generics;
630pub mod serde;
631pub mod std_traits;
632#[cfg(feature = "debug_stack")]
633mod type_info_stack;
634pub mod utility;
635
636/// The reflect prelude.
637///
638/// This includes the most common types in this crate, re-exported for your convenience.
639pub mod prelude {
640    pub use crate::std_traits::*;
641
642    #[doc(hidden)]
643    pub use crate::{
644        reflect_trait, FromReflect, GetField, GetPath, GetTupleStructField, PartialReflect,
645        Reflect, ReflectDeserialize, ReflectFromReflect, ReflectPath, ReflectSerialize, Struct,
646        TupleStruct, TypePath,
647    };
648
649    #[cfg(feature = "functions")]
650    pub use crate::func::{Function, IntoFunction, IntoFunctionMut};
651}
652
653pub use array::*;
654pub use enums::*;
655pub use error::*;
656pub use fields::*;
657pub use from_reflect::*;
658pub use generics::*;
659pub use is::*;
660pub use kind::*;
661pub use list::*;
662pub use map::*;
663pub use path::*;
664pub use reflect::*;
665pub use reflectable::*;
666pub use remote::*;
667pub use set::*;
668pub use struct_trait::*;
669pub use tuple::*;
670pub use tuple_struct::*;
671pub use type_info::*;
672pub use type_path::*;
673pub use type_registry::*;
674
675pub use bevy_reflect_derive::*;
676pub use erased_serde;
677
678/// Exports used by the reflection macros.
679///
680/// These are not meant to be used directly and are subject to breaking changes.
681#[doc(hidden)]
682pub mod __macro_exports {
683    use crate::{
684        DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicStruct, DynamicTuple,
685        DynamicTupleStruct, GetTypeRegistration, TypeRegistry,
686    };
687
688    /// Re-exports of items from the [`alloc`] crate.
689    ///
690    /// This is required because in `std` environments (e.g., the `std` feature is enabled)
691    /// the `alloc` crate may not have been included, making its namespace unreliable.
692    pub mod alloc_utils {
693        pub use ::alloc::{
694            borrow::{Cow, ToOwned},
695            boxed::Box,
696            string::ToString,
697        };
698    }
699
700    /// A wrapper trait around [`GetTypeRegistration`].
701    ///
702    /// This trait is used by the derive macro to recursively register all type dependencies.
703    /// It's used instead of `GetTypeRegistration` directly to avoid making dynamic types also
704    /// implement `GetTypeRegistration` in order to be used as active fields.
705    ///
706    /// This trait has a blanket implementation for all types that implement `GetTypeRegistration`
707    /// and manual implementations for all dynamic types (which simply do nothing).
708    #[diagnostic::on_unimplemented(
709        message = "`{Self}` does not implement `GetTypeRegistration` so cannot be registered for reflection",
710        note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
711    )]
712    pub trait RegisterForReflection {
713        #[expect(
714            unused_variables,
715            reason = "The parameters here are intentionally unused by the default implementation; however, putting underscores here will result in the underscores being copied by rust-analyzer's tab completion."
716        )]
717        fn __register(registry: &mut TypeRegistry) {}
718    }
719
720    impl<T: GetTypeRegistration> RegisterForReflection for T {
721        fn __register(registry: &mut TypeRegistry) {
722            registry.register::<T>();
723        }
724    }
725
726    impl RegisterForReflection for DynamicEnum {}
727
728    impl RegisterForReflection for DynamicTupleStruct {}
729
730    impl RegisterForReflection for DynamicStruct {}
731
732    impl RegisterForReflection for DynamicMap {}
733
734    impl RegisterForReflection for DynamicList {}
735
736    impl RegisterForReflection for DynamicArray {}
737
738    impl RegisterForReflection for DynamicTuple {}
739
740    /// Automatic reflect registration implementation
741    #[cfg(feature = "auto_register")]
742    pub mod auto_register {
743        pub use super::*;
744
745        #[cfg(all(
746            not(feature = "auto_register_inventory"),
747            not(feature = "auto_register_static")
748        ))]
749        compile_error!(
750            "Choosing a backend is required for automatic reflect registration. Please enable either the \"auto_register_inventory\" or the \"auto_register_static\" feature."
751        );
752
753        /// inventory impl
754        #[cfg(all(
755            not(feature = "auto_register_static"),
756            feature = "auto_register_inventory"
757        ))]
758        mod __automatic_type_registration_impl {
759            use super::*;
760
761            pub use inventory;
762
763            /// Stores type registration functions
764            pub struct AutomaticReflectRegistrations(pub fn(&mut TypeRegistry));
765
766            /// Registers all collected types.
767            pub fn register_types(registry: &mut TypeRegistry) {
768                #[cfg(target_family = "wasm")]
769                wasm_support::init();
770                for registration_fn in inventory::iter::<AutomaticReflectRegistrations> {
771                    registration_fn.0(registry);
772                }
773            }
774
775            inventory::collect!(AutomaticReflectRegistrations);
776
777            #[cfg(target_family = "wasm")]
778            mod wasm_support {
779                use bevy_platform::sync::atomic::{AtomicBool, Ordering};
780
781                static INIT_DONE: AtomicBool = AtomicBool::new(false);
782
783                #[expect(unsafe_code, reason = "This function is generated by linker.")]
784                unsafe extern "C" {
785                    fn __wasm_call_ctors();
786                }
787
788                /// This function must be called before using [`inventory::iter`] on [`AutomaticReflectRegistrations`] to run constructors on all platforms.
789                pub fn init() {
790                    if INIT_DONE.swap(true, Ordering::Relaxed) {
791                        return;
792                    };
793                    // SAFETY:
794                    // This will call constructors on wasm platforms at most once (as long as `init` is the only function that calls `__wasm_call_ctors`).
795                    //
796                    // For more information see: https://docs.rs/inventory/latest/inventory/#webassembly-and-constructors
797                    #[expect(
798                        unsafe_code,
799                        reason = "This function must be called to use inventory on wasm."
800                    )]
801                    unsafe {
802                        __wasm_call_ctors();
803                    }
804                }
805            }
806        }
807
808        /// static impl
809        #[cfg(feature = "auto_register_static")]
810        mod __automatic_type_registration_impl {
811            use super::*;
812            use alloc::vec::Vec;
813            use bevy_platform::sync::Mutex;
814
815            static REGISTRATION_FNS: Mutex<Vec<fn(&mut TypeRegistry)>> = Mutex::new(Vec::new());
816
817            /// Adds adds a new registration function for [`TypeRegistry`]
818            pub fn push_registration_fn(registration_fn: fn(&mut TypeRegistry)) {
819                REGISTRATION_FNS.lock().unwrap().push(registration_fn);
820            }
821
822            /// Registers all collected types.
823            pub fn register_types(registry: &mut TypeRegistry) {
824                for func in REGISTRATION_FNS.lock().unwrap().iter() {
825                    (func)(registry);
826                }
827            }
828        }
829
830        #[cfg(any(feature = "auto_register_static", feature = "auto_register_inventory"))]
831        pub use __automatic_type_registration_impl::*;
832    }
833}
834
835#[cfg(test)]
836#[expect(
837    clippy::approx_constant,
838    reason = "We don't need the exact value of Pi here."
839)]
840mod tests {
841    use ::serde::{de::DeserializeSeed, Deserialize, Serialize};
842    use alloc::{
843        borrow::Cow,
844        boxed::Box,
845        format,
846        string::{String, ToString},
847        vec,
848        vec::Vec,
849    };
850    use bevy_platform::collections::HashMap;
851    use core::{
852        any::TypeId,
853        fmt::{Debug, Formatter},
854        hash::Hash,
855        marker::PhantomData,
856    };
857    use disqualified::ShortName;
858    use ron::{
859        ser::{to_string_pretty, PrettyConfig},
860        Deserializer,
861    };
862    use static_assertions::{assert_impl_all, assert_not_impl_all};
863
864    use super::{prelude::*, *};
865    use crate::{
866        serde::{ReflectDeserializer, ReflectSerializer},
867        utility::GenericTypePathCell,
868    };
869
870    #[test]
871    fn try_apply_should_detect_kinds() {
872        #[derive(Reflect, Debug)]
873        struct Struct {
874            a: u32,
875            b: f32,
876        }
877
878        #[derive(Reflect, Debug)]
879        enum Enum {
880            A,
881            B(u32),
882        }
883
884        let mut struct_target = Struct {
885            a: 0xDEADBEEF,
886            b: 3.14,
887        };
888
889        let mut enum_target = Enum::A;
890
891        let array_src = [8, 0, 8];
892
893        let result = struct_target.try_apply(&enum_target);
894        assert!(
895            matches!(
896                result,
897                Err(ApplyError::MismatchedKinds {
898                    from_kind: ReflectKind::Enum,
899                    to_kind: ReflectKind::Struct
900                })
901            ),
902            "result was {result:?}"
903        );
904
905        let result = enum_target.try_apply(&array_src);
906        assert!(
907            matches!(
908                result,
909                Err(ApplyError::MismatchedKinds {
910                    from_kind: ReflectKind::Array,
911                    to_kind: ReflectKind::Enum
912                })
913            ),
914            "result was {result:?}"
915        );
916    }
917
918    #[test]
919    fn reflect_struct() {
920        #[derive(Reflect)]
921        struct Foo {
922            a: u32,
923            b: f32,
924            c: Bar,
925        }
926        #[derive(Reflect)]
927        struct Bar {
928            x: u32,
929        }
930
931        let mut foo = Foo {
932            a: 42,
933            b: 3.14,
934            c: Bar { x: 1 },
935        };
936
937        let a = *foo.get_field::<u32>("a").unwrap();
938        assert_eq!(a, 42);
939
940        *foo.get_field_mut::<u32>("a").unwrap() += 1;
941        assert_eq!(foo.a, 43);
942
943        let bar = foo.get_field::<Bar>("c").unwrap();
944        assert_eq!(bar.x, 1);
945
946        // nested retrieval
947        let c = foo.field("c").unwrap();
948        let value = c.reflect_ref().as_struct().unwrap();
949        assert_eq!(*value.get_field::<u32>("x").unwrap(), 1);
950
951        // patch Foo with a dynamic struct
952        let mut dynamic_struct = DynamicStruct::default();
953        dynamic_struct.insert("a", 123u32);
954        dynamic_struct.insert("should_be_ignored", 456);
955
956        foo.apply(&dynamic_struct);
957        assert_eq!(foo.a, 123);
958    }
959
960    #[test]
961    fn reflect_map() {
962        #[derive(Reflect, Hash)]
963        #[reflect(Hash)]
964        struct Foo {
965            a: u32,
966            b: String,
967        }
968
969        let key_a = Foo {
970            a: 1,
971            b: "k1".to_string(),
972        };
973
974        let key_b = Foo {
975            a: 1,
976            b: "k1".to_string(),
977        };
978
979        let key_c = Foo {
980            a: 3,
981            b: "k3".to_string(),
982        };
983
984        let mut map = DynamicMap::default();
985        map.insert(key_a, 10u32);
986        assert_eq!(
987            10,
988            *map.get(&key_b).unwrap().try_downcast_ref::<u32>().unwrap()
989        );
990        assert!(map.get(&key_c).is_none());
991        *map.get_mut(&key_b)
992            .unwrap()
993            .try_downcast_mut::<u32>()
994            .unwrap() = 20;
995        assert_eq!(
996            20,
997            *map.get(&key_b).unwrap().try_downcast_ref::<u32>().unwrap()
998        );
999    }
1000
1001    #[test]
1002    fn reflect_unit_struct() {
1003        #[derive(Reflect)]
1004        struct Foo(u32, u64);
1005
1006        let mut foo = Foo(1, 2);
1007        assert_eq!(1, *foo.get_field::<u32>(0).unwrap());
1008        assert_eq!(2, *foo.get_field::<u64>(1).unwrap());
1009
1010        let mut patch = DynamicTupleStruct::default();
1011        patch.insert(3u32);
1012        patch.insert(4u64);
1013        assert_eq!(
1014            3,
1015            *patch.field(0).unwrap().try_downcast_ref::<u32>().unwrap()
1016        );
1017        assert_eq!(
1018            4,
1019            *patch.field(1).unwrap().try_downcast_ref::<u64>().unwrap()
1020        );
1021
1022        foo.apply(&patch);
1023        assert_eq!(3, foo.0);
1024        assert_eq!(4, foo.1);
1025
1026        let mut iter = patch.iter_fields();
1027        assert_eq!(3, *iter.next().unwrap().try_downcast_ref::<u32>().unwrap());
1028        assert_eq!(4, *iter.next().unwrap().try_downcast_ref::<u64>().unwrap());
1029    }
1030
1031    #[test]
1032    #[should_panic(
1033        expected = "the given key of type `bevy_reflect::tests::Foo` does not support hashing"
1034    )]
1035    fn reflect_map_no_hash() {
1036        #[derive(Reflect)]
1037        struct Foo {
1038            a: u32,
1039        }
1040
1041        let foo = Foo { a: 1 };
1042        assert!(foo.reflect_hash().is_none());
1043
1044        let mut map = DynamicMap::default();
1045        map.insert(foo, 10u32);
1046    }
1047
1048    #[test]
1049    #[should_panic(
1050        expected = "the dynamic type `bevy_reflect::DynamicStruct` (representing `bevy_reflect::tests::Foo`) does not support hashing"
1051    )]
1052    fn reflect_map_no_hash_dynamic_representing() {
1053        #[derive(Reflect, Hash)]
1054        #[reflect(Hash)]
1055        struct Foo {
1056            a: u32,
1057        }
1058
1059        let foo = Foo { a: 1 };
1060        assert!(foo.reflect_hash().is_some());
1061        let dynamic = foo.to_dynamic_struct();
1062
1063        let mut map = DynamicMap::default();
1064        map.insert(dynamic, 11u32);
1065    }
1066
1067    #[test]
1068    #[should_panic(
1069        expected = "the dynamic type `bevy_reflect::DynamicStruct` does not support hashing"
1070    )]
1071    fn reflect_map_no_hash_dynamic() {
1072        #[allow(
1073            clippy::allow_attributes,
1074            dead_code,
1075            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1076        )]
1077        #[derive(Reflect, Hash)]
1078        #[reflect(Hash)]
1079        struct Foo {
1080            a: u32,
1081        }
1082
1083        let mut dynamic = DynamicStruct::default();
1084        dynamic.insert("a", 4u32);
1085        assert!(dynamic.reflect_hash().is_none());
1086
1087        let mut map = DynamicMap::default();
1088        map.insert(dynamic, 11u32);
1089    }
1090
1091    #[test]
1092    fn reflect_ignore() {
1093        #[derive(Reflect)]
1094        struct Foo {
1095            a: u32,
1096            #[reflect(ignore)]
1097            _b: u32,
1098        }
1099
1100        let foo = Foo { a: 1, _b: 2 };
1101
1102        let values: Vec<u32> = foo
1103            .iter_fields()
1104            .map(|value| *value.try_downcast_ref::<u32>().unwrap())
1105            .collect();
1106        assert_eq!(values, vec![1]);
1107    }
1108
1109    /// This test ensures that we are able to reflect generic types with one or more type parameters.
1110    ///
1111    /// When there is an `Add` implementation for `String`, the compiler isn't able to infer the correct
1112    /// type to deref to.
1113    /// If we don't append the strings in the `TypePath` derive correctly (i.e. explicitly specifying the type),
1114    /// we'll get a compilation error saying that "`&String` cannot be added to `String`".
1115    ///
1116    /// So this test just ensures that we do that correctly.
1117    ///
1118    /// This problem is a known issue and is unexpectedly expected behavior:
1119    /// - <https://github.com/rust-lang/rust/issues/77143>
1120    /// - <https://github.com/bodil/smartstring/issues/7>
1121    /// - <https://github.com/pola-rs/polars/issues/14666>
1122    #[test]
1123    fn should_reflect_generic() {
1124        struct FakeString {}
1125
1126        // This implementation confuses the compiler when trying to add a `&String` to a `String`
1127        impl core::ops::Add<FakeString> for String {
1128            type Output = Self;
1129            fn add(self, _rhs: FakeString) -> Self::Output {
1130                unreachable!()
1131            }
1132        }
1133
1134        #[expect(
1135            dead_code,
1136            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1137        )]
1138        #[derive(Reflect)]
1139        struct Foo<A>(A);
1140
1141        #[expect(
1142            dead_code,
1143            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1144        )]
1145        #[derive(Reflect)]
1146        struct Bar<A, B>(A, B);
1147
1148        #[expect(
1149            dead_code,
1150            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1151        )]
1152        #[derive(Reflect)]
1153        struct Baz<A, B, C>(A, B, C);
1154    }
1155
1156    #[test]
1157    fn should_reflect_clone() {
1158        // Struct
1159        #[derive(Reflect, Debug, PartialEq)]
1160        struct Foo(usize);
1161
1162        let value = Foo(123);
1163        let clone = value.reflect_clone().expect("should reflect_clone struct");
1164        assert_eq!(value, clone.take::<Foo>().unwrap());
1165
1166        // Tuple
1167        let foo = (123, 4.56);
1168        let clone = foo.reflect_clone().expect("should reflect_clone tuple");
1169        assert_eq!(foo, clone.take::<(u32, f32)>().unwrap());
1170    }
1171
1172    #[test]
1173    fn should_reflect_clone_generic_type() {
1174        #[derive(Reflect, Debug, PartialEq)]
1175        struct Foo<T, U>(T, #[reflect(ignore, clone)] PhantomData<U>);
1176        #[derive(TypePath, Debug, PartialEq)]
1177        struct Bar;
1178
1179        // `usize` will be cloned via `Reflect::reflect_clone`
1180        // `PhantomData<Bar>` will be cloned via `Clone::clone`
1181        let value = Foo::<usize, Bar>(123, PhantomData);
1182        let clone = value
1183            .reflect_clone()
1184            .expect("should reflect_clone generic struct");
1185        assert_eq!(value, clone.take::<Foo<usize, Bar>>().unwrap());
1186    }
1187
1188    #[test]
1189    fn should_reflect_clone_with_clone() {
1190        // A custom clone function to verify that the `#[reflect(Clone)]` container attribute
1191        // takes precedence over the `#[reflect(clone)]` field attribute.
1192        #[expect(
1193            dead_code,
1194            reason = "if things are working correctly, this function should never be called"
1195        )]
1196        fn custom_clone(_value: &usize) -> usize {
1197            panic!("should not be called");
1198        }
1199
1200        // Tuple Struct
1201        #[derive(Reflect, Clone, Debug, PartialEq)]
1202        #[reflect(Clone)]
1203        struct Foo(#[reflect(clone = "custom_clone")] usize);
1204
1205        let value = Foo(123);
1206        let clone = value
1207            .reflect_clone()
1208            .expect("should reflect_clone tuple struct");
1209        assert_eq!(value, clone.take::<Foo>().unwrap());
1210
1211        // Struct
1212        #[derive(Reflect, Clone, Debug, PartialEq)]
1213        #[reflect(Clone)]
1214        struct Bar {
1215            #[reflect(clone = "custom_clone")]
1216            value: usize,
1217        }
1218
1219        let value = Bar { value: 123 };
1220        let clone = value.reflect_clone().expect("should reflect_clone struct");
1221        assert_eq!(value, clone.take::<Bar>().unwrap());
1222
1223        // Enum
1224        #[derive(Reflect, Clone, Debug, PartialEq)]
1225        #[reflect(Clone)]
1226        enum Baz {
1227            Unit,
1228            Tuple(#[reflect(clone = "custom_clone")] usize),
1229            Struct {
1230                #[reflect(clone = "custom_clone")]
1231                value: usize,
1232            },
1233        }
1234
1235        let value = Baz::Unit;
1236        let clone = value
1237            .reflect_clone()
1238            .expect("should reflect_clone unit variant");
1239        assert_eq!(value, clone.take::<Baz>().unwrap());
1240
1241        let value = Baz::Tuple(123);
1242        let clone = value
1243            .reflect_clone()
1244            .expect("should reflect_clone tuple variant");
1245        assert_eq!(value, clone.take::<Baz>().unwrap());
1246
1247        let value = Baz::Struct { value: 123 };
1248        let clone = value
1249            .reflect_clone()
1250            .expect("should reflect_clone struct variant");
1251        assert_eq!(value, clone.take::<Baz>().unwrap());
1252    }
1253
1254    #[test]
1255    fn should_custom_reflect_clone() {
1256        #[derive(Reflect, Debug, PartialEq)]
1257        #[reflect(Clone(clone_foo))]
1258        struct Foo(usize);
1259
1260        fn clone_foo(foo: &Foo) -> Foo {
1261            Foo(foo.0 + 198)
1262        }
1263
1264        let foo = Foo(123);
1265        let clone = foo.reflect_clone().unwrap();
1266        assert_eq!(Foo(321), clone.take::<Foo>().unwrap());
1267    }
1268
1269    #[test]
1270    fn should_not_clone_ignored_fields() {
1271        // Tuple Struct
1272        #[derive(Reflect, Clone, Debug, PartialEq)]
1273        struct Foo(#[reflect(ignore)] usize);
1274
1275        let foo = Foo(123);
1276        let clone = foo.reflect_clone();
1277        assert_eq!(
1278            clone.unwrap_err(),
1279            ReflectCloneError::FieldNotCloneable {
1280                field: FieldId::Unnamed(0),
1281                variant: None,
1282                container_type_path: Cow::Borrowed(Foo::type_path()),
1283            }
1284        );
1285
1286        // Struct
1287        #[derive(Reflect, Clone, Debug, PartialEq)]
1288        struct Bar {
1289            #[reflect(ignore)]
1290            value: usize,
1291        }
1292
1293        let bar = Bar { value: 123 };
1294        let clone = bar.reflect_clone();
1295        assert_eq!(
1296            clone.unwrap_err(),
1297            ReflectCloneError::FieldNotCloneable {
1298                field: FieldId::Named(Cow::Borrowed("value")),
1299                variant: None,
1300                container_type_path: Cow::Borrowed(Bar::type_path()),
1301            }
1302        );
1303
1304        // Enum
1305        #[derive(Reflect, Clone, Debug, PartialEq)]
1306        enum Baz {
1307            Tuple(#[reflect(ignore)] usize),
1308            Struct {
1309                #[reflect(ignore)]
1310                value: usize,
1311            },
1312        }
1313
1314        let baz = Baz::Tuple(123);
1315        let clone = baz.reflect_clone();
1316        assert_eq!(
1317            clone.unwrap_err(),
1318            ReflectCloneError::FieldNotCloneable {
1319                field: FieldId::Unnamed(0),
1320                variant: Some(Cow::Borrowed("Tuple")),
1321                container_type_path: Cow::Borrowed(Baz::type_path()),
1322            }
1323        );
1324
1325        let baz = Baz::Struct { value: 123 };
1326        let clone = baz.reflect_clone();
1327        assert_eq!(
1328            clone.unwrap_err(),
1329            ReflectCloneError::FieldNotCloneable {
1330                field: FieldId::Named(Cow::Borrowed("value")),
1331                variant: Some(Cow::Borrowed("Struct")),
1332                container_type_path: Cow::Borrowed(Baz::type_path()),
1333            }
1334        );
1335    }
1336
1337    #[test]
1338    fn should_clone_ignored_fields_with_clone_attributes() {
1339        #[derive(Reflect, Clone, Debug, PartialEq)]
1340        struct Foo(#[reflect(ignore, clone)] usize);
1341
1342        let foo = Foo(123);
1343        let clone = foo.reflect_clone().unwrap();
1344        assert_eq!(Foo(123), clone.take::<Foo>().unwrap());
1345
1346        #[derive(Reflect, Clone, Debug, PartialEq)]
1347        struct Bar(#[reflect(ignore, clone = "clone_usize")] usize);
1348
1349        fn clone_usize(this: &usize) -> usize {
1350            *this + 198
1351        }
1352
1353        let bar = Bar(123);
1354        let clone = bar.reflect_clone().unwrap();
1355        assert_eq!(Bar(321), clone.take::<Bar>().unwrap());
1356    }
1357
1358    #[test]
1359    fn should_composite_reflect_clone() {
1360        #[derive(Reflect, Debug, PartialEq)]
1361        enum MyEnum {
1362            Unit,
1363            Tuple(
1364                Foo,
1365                #[reflect(ignore, clone)] Bar,
1366                #[reflect(clone = "clone_baz")] Baz,
1367            ),
1368            Struct {
1369                foo: Foo,
1370                #[reflect(ignore, clone)]
1371                bar: Bar,
1372                #[reflect(clone = "clone_baz")]
1373                baz: Baz,
1374            },
1375        }
1376
1377        #[derive(Reflect, Debug, PartialEq)]
1378        struct Foo {
1379            #[reflect(clone = "clone_bar")]
1380            bar: Bar,
1381            baz: Baz,
1382        }
1383
1384        #[derive(Reflect, Default, Clone, Debug, PartialEq)]
1385        #[reflect(Clone)]
1386        struct Bar(String);
1387
1388        #[derive(Reflect, Debug, PartialEq)]
1389        struct Baz(String);
1390
1391        fn clone_bar(bar: &Bar) -> Bar {
1392            Bar(format!("{}!", bar.0))
1393        }
1394
1395        fn clone_baz(baz: &Baz) -> Baz {
1396            Baz(format!("{}!", baz.0))
1397        }
1398
1399        let my_enum = MyEnum::Unit;
1400        let clone = my_enum.reflect_clone().unwrap();
1401        assert_eq!(MyEnum::Unit, clone.take::<MyEnum>().unwrap());
1402
1403        let my_enum = MyEnum::Tuple(
1404            Foo {
1405                bar: Bar("bar".to_string()),
1406                baz: Baz("baz".to_string()),
1407            },
1408            Bar("bar".to_string()),
1409            Baz("baz".to_string()),
1410        );
1411        let clone = my_enum.reflect_clone().unwrap();
1412        assert_eq!(
1413            MyEnum::Tuple(
1414                Foo {
1415                    bar: Bar("bar!".to_string()),
1416                    baz: Baz("baz".to_string()),
1417                },
1418                Bar("bar".to_string()),
1419                Baz("baz!".to_string()),
1420            ),
1421            clone.take::<MyEnum>().unwrap()
1422        );
1423
1424        let my_enum = MyEnum::Struct {
1425            foo: Foo {
1426                bar: Bar("bar".to_string()),
1427                baz: Baz("baz".to_string()),
1428            },
1429            bar: Bar("bar".to_string()),
1430            baz: Baz("baz".to_string()),
1431        };
1432        let clone = my_enum.reflect_clone().unwrap();
1433        assert_eq!(
1434            MyEnum::Struct {
1435                foo: Foo {
1436                    bar: Bar("bar!".to_string()),
1437                    baz: Baz("baz".to_string()),
1438                },
1439                bar: Bar("bar".to_string()),
1440                baz: Baz("baz!".to_string()),
1441            },
1442            clone.take::<MyEnum>().unwrap()
1443        );
1444    }
1445
1446    #[test]
1447    fn should_call_from_reflect_dynamically() {
1448        #[derive(Reflect)]
1449        struct MyStruct {
1450            foo: usize,
1451        }
1452
1453        // Register
1454        let mut registry = TypeRegistry::default();
1455        registry.register::<MyStruct>();
1456
1457        // Get type data
1458        let type_id = TypeId::of::<MyStruct>();
1459        let rfr = registry
1460            .get_type_data::<ReflectFromReflect>(type_id)
1461            .expect("the FromReflect trait should be registered");
1462
1463        // Call from_reflect
1464        let mut dynamic_struct = DynamicStruct::default();
1465        dynamic_struct.insert("foo", 123usize);
1466        let reflected = rfr
1467            .from_reflect(&dynamic_struct)
1468            .expect("the type should be properly reflected");
1469
1470        // Assert
1471        let expected = MyStruct { foo: 123 };
1472        assert!(expected
1473            .reflect_partial_eq(reflected.as_partial_reflect())
1474            .unwrap_or_default());
1475        let not_expected = MyStruct { foo: 321 };
1476        assert!(!not_expected
1477            .reflect_partial_eq(reflected.as_partial_reflect())
1478            .unwrap_or_default());
1479    }
1480
1481    #[test]
1482    fn from_reflect_should_allow_ignored_unnamed_fields() {
1483        #[derive(Reflect, Eq, PartialEq, Debug)]
1484        struct MyTupleStruct(i8, #[reflect(ignore)] i16, i32);
1485
1486        let expected = MyTupleStruct(1, 0, 3);
1487
1488        let mut dyn_tuple_struct = DynamicTupleStruct::default();
1489        dyn_tuple_struct.insert(1_i8);
1490        dyn_tuple_struct.insert(3_i32);
1491        let my_tuple_struct = <MyTupleStruct as FromReflect>::from_reflect(&dyn_tuple_struct);
1492
1493        assert_eq!(Some(expected), my_tuple_struct);
1494
1495        #[derive(Reflect, Eq, PartialEq, Debug)]
1496        enum MyEnum {
1497            Tuple(i8, #[reflect(ignore)] i16, i32),
1498        }
1499
1500        let expected = MyEnum::Tuple(1, 0, 3);
1501
1502        let mut dyn_tuple = DynamicTuple::default();
1503        dyn_tuple.insert(1_i8);
1504        dyn_tuple.insert(3_i32);
1505
1506        let mut dyn_enum = DynamicEnum::default();
1507        dyn_enum.set_variant("Tuple", dyn_tuple);
1508
1509        let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
1510
1511        assert_eq!(Some(expected), my_enum);
1512    }
1513
1514    #[test]
1515    fn from_reflect_should_use_default_field_attributes() {
1516        #[derive(Reflect, Eq, PartialEq, Debug)]
1517        struct MyStruct {
1518            // Use `Default::default()`
1519            // Note that this isn't an ignored field
1520            #[reflect(default)]
1521            foo: String,
1522
1523            // Use `get_bar_default()`
1524            #[reflect(ignore)]
1525            #[reflect(default = "get_bar_default")]
1526            bar: NotReflect,
1527
1528            // Ensure attributes can be combined
1529            #[reflect(ignore, default = "get_bar_default")]
1530            baz: NotReflect,
1531        }
1532
1533        #[derive(Eq, PartialEq, Debug)]
1534        struct NotReflect(usize);
1535
1536        fn get_bar_default() -> NotReflect {
1537            NotReflect(123)
1538        }
1539
1540        let expected = MyStruct {
1541            foo: String::default(),
1542            bar: NotReflect(123),
1543            baz: NotReflect(123),
1544        };
1545
1546        let dyn_struct = DynamicStruct::default();
1547        let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
1548
1549        assert_eq!(Some(expected), my_struct);
1550    }
1551
1552    #[test]
1553    fn from_reflect_should_use_default_variant_field_attributes() {
1554        #[derive(Reflect, Eq, PartialEq, Debug)]
1555        enum MyEnum {
1556            Foo(#[reflect(default)] String),
1557            Bar {
1558                #[reflect(default = "get_baz_default")]
1559                #[reflect(ignore)]
1560                baz: usize,
1561            },
1562        }
1563
1564        fn get_baz_default() -> usize {
1565            123
1566        }
1567
1568        let expected = MyEnum::Foo(String::default());
1569
1570        let dyn_enum = DynamicEnum::new("Foo", DynamicTuple::default());
1571        let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
1572
1573        assert_eq!(Some(expected), my_enum);
1574
1575        let expected = MyEnum::Bar {
1576            baz: get_baz_default(),
1577        };
1578
1579        let dyn_enum = DynamicEnum::new("Bar", DynamicStruct::default());
1580        let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
1581
1582        assert_eq!(Some(expected), my_enum);
1583    }
1584
1585    #[test]
1586    fn from_reflect_should_use_default_container_attribute() {
1587        #[derive(Reflect, Eq, PartialEq, Debug)]
1588        #[reflect(Default)]
1589        struct MyStruct {
1590            foo: String,
1591            #[reflect(ignore)]
1592            bar: usize,
1593        }
1594
1595        impl Default for MyStruct {
1596            fn default() -> Self {
1597                Self {
1598                    foo: String::from("Hello"),
1599                    bar: 123,
1600                }
1601            }
1602        }
1603
1604        let expected = MyStruct {
1605            foo: String::from("Hello"),
1606            bar: 123,
1607        };
1608
1609        let dyn_struct = DynamicStruct::default();
1610        let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
1611
1612        assert_eq!(Some(expected), my_struct);
1613    }
1614
1615    #[test]
1616    fn reflect_complex_patch() {
1617        #[derive(Reflect, Eq, PartialEq, Debug)]
1618        #[reflect(PartialEq)]
1619        struct Foo {
1620            a: u32,
1621            #[reflect(ignore)]
1622            _b: u32,
1623            c: Vec<isize>,
1624            d: HashMap<usize, i8>,
1625            e: Bar,
1626            f: (i32, Vec<isize>, Bar),
1627            g: Vec<(Baz, HashMap<usize, Bar>)>,
1628            h: [u32; 2],
1629        }
1630
1631        #[derive(Reflect, Eq, PartialEq, Clone, Debug)]
1632        #[reflect(PartialEq)]
1633        struct Bar {
1634            x: u32,
1635        }
1636
1637        #[derive(Reflect, Eq, PartialEq, Debug)]
1638        struct Baz(String);
1639
1640        let mut hash_map = <HashMap<_, _>>::default();
1641        hash_map.insert(1, 1);
1642        hash_map.insert(2, 2);
1643
1644        let mut hash_map_baz = <HashMap<_, _>>::default();
1645        hash_map_baz.insert(1, Bar { x: 0 });
1646
1647        let mut foo = Foo {
1648            a: 1,
1649            _b: 1,
1650            c: vec![1, 2],
1651            d: hash_map,
1652            e: Bar { x: 1 },
1653            f: (1, vec![1, 2], Bar { x: 1 }),
1654            g: vec![(Baz("string".to_string()), hash_map_baz)],
1655            h: [2; 2],
1656        };
1657
1658        let mut foo_patch = DynamicStruct::default();
1659        foo_patch.insert("a", 2u32);
1660        foo_patch.insert("b", 2u32); // this should be ignored
1661
1662        let mut list = DynamicList::default();
1663        list.push(3isize);
1664        list.push(4isize);
1665        list.push(5isize);
1666        foo_patch.insert("c", list.to_dynamic_list());
1667
1668        let mut map = DynamicMap::default();
1669        map.insert(2usize, 3i8);
1670        map.insert(3usize, 4i8);
1671        foo_patch.insert("d", map);
1672
1673        let mut bar_patch = DynamicStruct::default();
1674        bar_patch.insert("x", 2u32);
1675        foo_patch.insert("e", bar_patch.to_dynamic_struct());
1676
1677        let mut tuple = DynamicTuple::default();
1678        tuple.insert(2i32);
1679        tuple.insert(list);
1680        tuple.insert(bar_patch);
1681        foo_patch.insert("f", tuple);
1682
1683        let mut composite = DynamicList::default();
1684        composite.push({
1685            let mut tuple = DynamicTuple::default();
1686            tuple.insert({
1687                let mut tuple_struct = DynamicTupleStruct::default();
1688                tuple_struct.insert("new_string".to_string());
1689                tuple_struct
1690            });
1691            tuple.insert({
1692                let mut map = DynamicMap::default();
1693                map.insert(1usize, {
1694                    let mut struct_ = DynamicStruct::default();
1695                    struct_.insert("x", 7u32);
1696                    struct_
1697                });
1698                map
1699            });
1700            tuple
1701        });
1702        foo_patch.insert("g", composite);
1703
1704        let array = DynamicArray::from_iter([2u32, 2u32]);
1705        foo_patch.insert("h", array);
1706
1707        foo.apply(&foo_patch);
1708
1709        let mut hash_map = <HashMap<_, _>>::default();
1710        hash_map.insert(2, 3);
1711        hash_map.insert(3, 4);
1712
1713        let mut hash_map_baz = <HashMap<_, _>>::default();
1714        hash_map_baz.insert(1, Bar { x: 7 });
1715
1716        let expected_foo = Foo {
1717            a: 2,
1718            _b: 1,
1719            c: vec![3, 4, 5],
1720            d: hash_map,
1721            e: Bar { x: 2 },
1722            f: (2, vec![3, 4, 5], Bar { x: 2 }),
1723            g: vec![(Baz("new_string".to_string()), hash_map_baz.clone())],
1724            h: [2; 2],
1725        };
1726
1727        assert_eq!(foo, expected_foo);
1728
1729        let new_foo = Foo::from_reflect(&foo_patch)
1730            .expect("error while creating a concrete type from a dynamic type");
1731
1732        let mut hash_map = <HashMap<_, _>>::default();
1733        hash_map.insert(2, 3);
1734        hash_map.insert(3, 4);
1735
1736        let expected_new_foo = Foo {
1737            a: 2,
1738            _b: 0,
1739            c: vec![3, 4, 5],
1740            d: hash_map,
1741            e: Bar { x: 2 },
1742            f: (2, vec![3, 4, 5], Bar { x: 2 }),
1743            g: vec![(Baz("new_string".to_string()), hash_map_baz)],
1744            h: [2; 2],
1745        };
1746
1747        assert_eq!(new_foo, expected_new_foo);
1748    }
1749
1750    #[test]
1751    fn should_auto_register_fields() {
1752        #[derive(Reflect)]
1753        struct Foo {
1754            bar: Bar,
1755        }
1756
1757        #[derive(Reflect)]
1758        enum Bar {
1759            Variant(Baz),
1760        }
1761
1762        #[derive(Reflect)]
1763        struct Baz(usize);
1764
1765        // === Basic === //
1766        let mut registry = TypeRegistry::empty();
1767        registry.register::<Foo>();
1768
1769        assert!(
1770            registry.contains(TypeId::of::<Bar>()),
1771            "registry should contain auto-registered `Bar` from `Foo`"
1772        );
1773
1774        // === Option === //
1775        let mut registry = TypeRegistry::empty();
1776        registry.register::<Option<Foo>>();
1777
1778        assert!(
1779            registry.contains(TypeId::of::<Bar>()),
1780            "registry should contain auto-registered `Bar` from `Option<Foo>`"
1781        );
1782
1783        // === Tuple === //
1784        let mut registry = TypeRegistry::empty();
1785        registry.register::<(Foo, Foo)>();
1786
1787        assert!(
1788            registry.contains(TypeId::of::<Bar>()),
1789            "registry should contain auto-registered `Bar` from `(Foo, Foo)`"
1790        );
1791
1792        // === Array === //
1793        let mut registry = TypeRegistry::empty();
1794        registry.register::<[Foo; 3]>();
1795
1796        assert!(
1797            registry.contains(TypeId::of::<Bar>()),
1798            "registry should contain auto-registered `Bar` from `[Foo; 3]`"
1799        );
1800
1801        // === Vec === //
1802        let mut registry = TypeRegistry::empty();
1803        registry.register::<Vec<Foo>>();
1804
1805        assert!(
1806            registry.contains(TypeId::of::<Bar>()),
1807            "registry should contain auto-registered `Bar` from `Vec<Foo>`"
1808        );
1809
1810        // === HashMap === //
1811        let mut registry = TypeRegistry::empty();
1812        registry.register::<HashMap<i32, Foo>>();
1813
1814        assert!(
1815            registry.contains(TypeId::of::<Bar>()),
1816            "registry should contain auto-registered `Bar` from `HashMap<i32, Foo>`"
1817        );
1818    }
1819
1820    #[test]
1821    fn should_allow_dynamic_fields() {
1822        #[derive(Reflect)]
1823        #[reflect(from_reflect = false)]
1824        struct MyStruct(
1825            DynamicEnum,
1826            DynamicTupleStruct,
1827            DynamicStruct,
1828            DynamicMap,
1829            DynamicList,
1830            DynamicArray,
1831            DynamicTuple,
1832            i32,
1833        );
1834
1835        assert_impl_all!(MyStruct: Reflect, GetTypeRegistration);
1836
1837        let mut registry = TypeRegistry::empty();
1838        registry.register::<MyStruct>();
1839
1840        assert_eq!(2, registry.iter().count());
1841        assert!(registry.contains(TypeId::of::<MyStruct>()));
1842        assert!(registry.contains(TypeId::of::<i32>()));
1843    }
1844
1845    #[test]
1846    fn should_not_auto_register_existing_types() {
1847        #[derive(Reflect)]
1848        struct Foo {
1849            bar: Bar,
1850        }
1851
1852        #[derive(Reflect, Default)]
1853        struct Bar(usize);
1854
1855        let mut registry = TypeRegistry::empty();
1856        registry.register::<Bar>();
1857        registry.register_type_data::<Bar, ReflectDefault>();
1858        registry.register::<Foo>();
1859
1860        assert!(
1861            registry
1862                .get_type_data::<ReflectDefault>(TypeId::of::<Bar>())
1863                .is_some(),
1864            "registry should contain existing registration for `Bar`"
1865        );
1866    }
1867
1868    #[test]
1869    fn reflect_serialize() {
1870        #[derive(Reflect)]
1871        struct Foo {
1872            a: u32,
1873            #[reflect(ignore)]
1874            _b: u32,
1875            c: Vec<isize>,
1876            d: HashMap<usize, i8>,
1877            e: Bar,
1878            f: String,
1879            g: (i32, Vec<isize>, Bar),
1880            h: [u32; 2],
1881        }
1882
1883        #[derive(Reflect, Serialize, Deserialize)]
1884        #[reflect(Serialize, Deserialize)]
1885        struct Bar {
1886            x: u32,
1887        }
1888
1889        let mut hash_map = <HashMap<_, _>>::default();
1890        hash_map.insert(1, 1);
1891        hash_map.insert(2, 2);
1892        let foo = Foo {
1893            a: 1,
1894            _b: 1,
1895            c: vec![1, 2],
1896            d: hash_map,
1897            e: Bar { x: 1 },
1898            f: "hi".to_string(),
1899            g: (1, vec![1, 2], Bar { x: 1 }),
1900            h: [2; 2],
1901        };
1902
1903        let mut registry = TypeRegistry::default();
1904        registry.register::<u32>();
1905        registry.register::<i8>();
1906        registry.register::<i32>();
1907        registry.register::<usize>();
1908        registry.register::<isize>();
1909        registry.register::<Foo>();
1910        registry.register::<Bar>();
1911        registry.register::<String>();
1912        registry.register::<Vec<isize>>();
1913        registry.register::<HashMap<usize, i8>>();
1914        registry.register::<(i32, Vec<isize>, Bar)>();
1915        registry.register::<[u32; 2]>();
1916
1917        let serializer = ReflectSerializer::new(&foo, &registry);
1918        let serialized = to_string_pretty(&serializer, PrettyConfig::default()).unwrap();
1919
1920        let mut deserializer = Deserializer::from_str(&serialized).unwrap();
1921        let reflect_deserializer = ReflectDeserializer::new(&registry);
1922        let value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
1923        let roundtrip_foo = Foo::from_reflect(value.as_partial_reflect()).unwrap();
1924
1925        assert!(foo.reflect_partial_eq(&roundtrip_foo).unwrap());
1926    }
1927
1928    #[test]
1929    fn reflect_downcast() {
1930        #[derive(Reflect, Clone, Debug, PartialEq)]
1931        struct Bar {
1932            y: u8,
1933        }
1934
1935        #[derive(Reflect, Clone, Debug, PartialEq)]
1936        struct Foo {
1937            x: i32,
1938            s: String,
1939            b: Bar,
1940            u: usize,
1941            t: ([f32; 3], String),
1942            v: Cow<'static, str>,
1943            w: Cow<'static, [u8]>,
1944        }
1945
1946        let foo = Foo {
1947            x: 123,
1948            s: "String".to_string(),
1949            b: Bar { y: 255 },
1950            u: 1111111111111,
1951            t: ([3.0, 2.0, 1.0], "Tuple String".to_string()),
1952            v: Cow::Owned("Cow String".to_string()),
1953            w: Cow::Owned(vec![1, 2, 3]),
1954        };
1955
1956        let foo2: Box<dyn Reflect> = Box::new(foo.clone());
1957
1958        assert_eq!(foo, *foo2.downcast::<Foo>().unwrap());
1959    }
1960
1961    #[test]
1962    fn should_drain_fields() {
1963        let array_value: Box<dyn Array> = Box::new([123_i32, 321_i32]);
1964        let fields = array_value.drain();
1965        assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1966        assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1967
1968        let mut list_value: Box<dyn List> = Box::new(vec![123_i32, 321_i32]);
1969        let fields = list_value.drain();
1970        assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1971        assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1972
1973        let tuple_value: Box<dyn Tuple> = Box::new((123_i32, 321_i32));
1974        let fields = tuple_value.drain();
1975        assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1976        assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1977
1978        let mut map_value: Box<dyn Map> =
1979            Box::new([(123_i32, 321_i32)].into_iter().collect::<HashMap<_, _>>());
1980        let fields = map_value.drain();
1981        assert!(fields[0].0.reflect_partial_eq(&123_i32).unwrap_or_default());
1982        assert!(fields[0].1.reflect_partial_eq(&321_i32).unwrap_or_default());
1983    }
1984
1985    #[test]
1986    fn reflect_take() {
1987        #[derive(Reflect, Debug, PartialEq)]
1988        #[reflect(PartialEq)]
1989        struct Bar {
1990            x: u32,
1991        }
1992
1993        let x: Box<dyn Reflect> = Box::new(Bar { x: 2 });
1994        let y = x.take::<Bar>().unwrap();
1995        assert_eq!(y, Bar { x: 2 });
1996    }
1997
1998    #[test]
1999    fn not_dynamic_names() {
2000        let list = Vec::<usize>::new();
2001        let dyn_list = list.to_dynamic_list();
2002        assert_ne!(dyn_list.reflect_type_path(), Vec::<usize>::type_path());
2003
2004        let array = [b'0'; 4];
2005        let dyn_array = array.to_dynamic_array();
2006        assert_ne!(dyn_array.reflect_type_path(), <[u8; 4]>::type_path());
2007
2008        let map = HashMap::<usize, String>::default();
2009        let dyn_map = map.to_dynamic_map();
2010        assert_ne!(
2011            dyn_map.reflect_type_path(),
2012            HashMap::<usize, String>::type_path()
2013        );
2014
2015        let tuple = (0usize, "1".to_string(), 2.0f32);
2016        let mut dyn_tuple = tuple.to_dynamic_tuple();
2017        dyn_tuple.insert::<usize>(3);
2018        assert_ne!(
2019            dyn_tuple.reflect_type_path(),
2020            <(usize, String, f32, usize)>::type_path()
2021        );
2022
2023        #[derive(Reflect)]
2024        struct TestStruct {
2025            a: usize,
2026        }
2027        let struct_ = TestStruct { a: 0 };
2028        let dyn_struct = struct_.to_dynamic_struct();
2029        assert_ne!(dyn_struct.reflect_type_path(), TestStruct::type_path());
2030
2031        #[derive(Reflect)]
2032        struct TestTupleStruct(usize);
2033        let tuple_struct = TestTupleStruct(0);
2034        let dyn_tuple_struct = tuple_struct.to_dynamic_tuple_struct();
2035        assert_ne!(
2036            dyn_tuple_struct.reflect_type_path(),
2037            TestTupleStruct::type_path()
2038        );
2039    }
2040
2041    macro_rules! assert_type_paths {
2042        ($($ty:ty => $long:literal, $short:literal,)*) => {
2043            $(
2044                assert_eq!(<$ty as TypePath>::type_path(), $long);
2045                assert_eq!(<$ty as TypePath>::short_type_path(), $short);
2046            )*
2047        };
2048    }
2049
2050    #[test]
2051    fn reflect_type_path() {
2052        #[derive(TypePath)]
2053        struct Param;
2054
2055        #[derive(TypePath)]
2056        struct Derive;
2057
2058        #[derive(TypePath)]
2059        #[type_path = "my_alias"]
2060        struct DerivePath;
2061
2062        #[derive(TypePath)]
2063        #[type_path = "my_alias"]
2064        #[type_name = "MyDerivePathName"]
2065        struct DerivePathName;
2066
2067        #[derive(TypePath)]
2068        struct DeriveG<T>(PhantomData<T>);
2069
2070        #[derive(TypePath)]
2071        #[type_path = "my_alias"]
2072        struct DerivePathG<T, const N: usize>(PhantomData<T>);
2073
2074        #[derive(TypePath)]
2075        #[type_path = "my_alias"]
2076        #[type_name = "MyDerivePathNameG"]
2077        struct DerivePathNameG<T>(PhantomData<T>);
2078
2079        struct Macro;
2080        impl_type_path!((in my_alias) Macro);
2081
2082        struct MacroName;
2083        impl_type_path!((in my_alias as MyMacroName) MacroName);
2084
2085        struct MacroG<T, const N: usize>(PhantomData<T>);
2086        impl_type_path!((in my_alias) MacroG<T, const N: usize>);
2087
2088        struct MacroNameG<T>(PhantomData<T>);
2089        impl_type_path!((in my_alias as MyMacroNameG) MacroNameG<T>);
2090
2091        assert_type_paths! {
2092            Derive => "bevy_reflect::tests::Derive", "Derive",
2093            DerivePath => "my_alias::DerivePath", "DerivePath",
2094            DerivePathName => "my_alias::MyDerivePathName", "MyDerivePathName",
2095            DeriveG<Param> => "bevy_reflect::tests::DeriveG<bevy_reflect::tests::Param>", "DeriveG<Param>",
2096            DerivePathG<Param, 10> => "my_alias::DerivePathG<bevy_reflect::tests::Param, 10>", "DerivePathG<Param, 10>",
2097            DerivePathNameG<Param> => "my_alias::MyDerivePathNameG<bevy_reflect::tests::Param>", "MyDerivePathNameG<Param>",
2098            Macro => "my_alias::Macro", "Macro",
2099            MacroName => "my_alias::MyMacroName", "MyMacroName",
2100            MacroG<Param, 10> => "my_alias::MacroG<bevy_reflect::tests::Param, 10>", "MacroG<Param, 10>",
2101            MacroNameG<Param> => "my_alias::MyMacroNameG<bevy_reflect::tests::Param>", "MyMacroNameG<Param>",
2102        }
2103    }
2104
2105    #[test]
2106    fn std_type_paths() {
2107        #[derive(Clone)]
2108        struct Type;
2109
2110        impl TypePath for Type {
2111            fn type_path() -> &'static str {
2112                // for brevity in tests
2113                "Long"
2114            }
2115
2116            fn short_type_path() -> &'static str {
2117                "Short"
2118            }
2119        }
2120
2121        assert_type_paths! {
2122            u8 => "u8", "u8",
2123            Type => "Long", "Short",
2124            &Type => "&Long", "&Short",
2125            [Type] => "[Long]", "[Short]",
2126            &[Type] => "&[Long]", "&[Short]",
2127            [Type; 0] => "[Long; 0]", "[Short; 0]",
2128            [Type; 100] => "[Long; 100]", "[Short; 100]",
2129            () => "()", "()",
2130            (Type,) => "(Long,)", "(Short,)",
2131            (Type, Type) => "(Long, Long)", "(Short, Short)",
2132            (Type, Type, Type) => "(Long, Long, Long)", "(Short, Short, Short)",
2133            Cow<'static, Type> => "alloc::borrow::Cow<Long>", "Cow<Short>",
2134        }
2135    }
2136
2137    #[test]
2138    fn reflect_type_info() {
2139        // TypeInfo
2140        let info = i32::type_info();
2141        assert_eq!(i32::type_path(), info.type_path());
2142        assert_eq!(TypeId::of::<i32>(), info.type_id());
2143
2144        // TypeInfo (unsized)
2145        assert_eq!(
2146            TypeId::of::<dyn Reflect>(),
2147            <dyn Reflect as Typed>::type_info().type_id()
2148        );
2149
2150        // TypeInfo (instance)
2151        let value: &dyn Reflect = &123_i32;
2152        let info = value.reflect_type_info();
2153        assert!(info.is::<i32>());
2154
2155        // Struct
2156        #[derive(Reflect)]
2157        struct MyStruct {
2158            foo: i32,
2159            bar: usize,
2160        }
2161
2162        let info = MyStruct::type_info().as_struct().unwrap();
2163        assert!(info.is::<MyStruct>());
2164        assert_eq!(MyStruct::type_path(), info.type_path());
2165        assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
2166        assert_eq!(TypeId::of::<i32>(), info.field("foo").unwrap().type_id());
2167        assert!(info.field("foo").unwrap().type_info().unwrap().is::<i32>());
2168        assert!(info.field("foo").unwrap().is::<i32>());
2169        assert_eq!("foo", info.field("foo").unwrap().name());
2170        assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2171
2172        let value: &dyn Reflect = &MyStruct { foo: 123, bar: 321 };
2173        let info = value.reflect_type_info();
2174        assert!(info.is::<MyStruct>());
2175
2176        // Struct (generic)
2177        #[derive(Reflect)]
2178        struct MyGenericStruct<T> {
2179            foo: T,
2180            bar: usize,
2181        }
2182
2183        let info = <MyGenericStruct<i32>>::type_info().as_struct().unwrap();
2184        assert!(info.is::<MyGenericStruct<i32>>());
2185        assert_eq!(MyGenericStruct::<i32>::type_path(), info.type_path());
2186        assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
2187        assert_eq!("foo", info.field("foo").unwrap().name());
2188        assert!(info.field("foo").unwrap().type_info().unwrap().is::<i32>());
2189        assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2190
2191        let value: &dyn Reflect = &MyGenericStruct {
2192            foo: String::from("Hello!"),
2193            bar: 321,
2194        };
2195        let info = value.reflect_type_info();
2196        assert!(info.is::<MyGenericStruct<String>>());
2197
2198        // Struct (dynamic field)
2199        #[derive(Reflect)]
2200        #[reflect(from_reflect = false)]
2201        struct MyDynamicStruct {
2202            foo: DynamicStruct,
2203            bar: usize,
2204        }
2205
2206        let info = MyDynamicStruct::type_info();
2207        if let TypeInfo::Struct(info) = info {
2208            assert!(info.is::<MyDynamicStruct>());
2209            assert_eq!(MyDynamicStruct::type_path(), info.type_path());
2210            assert_eq!(
2211                DynamicStruct::type_path(),
2212                info.field("foo").unwrap().type_path()
2213            );
2214            assert_eq!("foo", info.field("foo").unwrap().name());
2215            assert!(info.field("foo").unwrap().type_info().is_none());
2216            assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2217        } else {
2218            panic!("Expected `TypeInfo::Struct`");
2219        }
2220
2221        let value: &dyn Reflect = &MyDynamicStruct {
2222            foo: DynamicStruct::default(),
2223            bar: 321,
2224        };
2225        let info = value.reflect_type_info();
2226        assert!(info.is::<MyDynamicStruct>());
2227
2228        // Tuple Struct
2229        #[derive(Reflect)]
2230        struct MyTupleStruct(usize, i32, MyStruct);
2231
2232        let info = MyTupleStruct::type_info().as_tuple_struct().unwrap();
2233
2234        assert!(info.is::<MyTupleStruct>());
2235        assert_eq!(MyTupleStruct::type_path(), info.type_path());
2236        assert_eq!(i32::type_path(), info.field_at(1).unwrap().type_path());
2237        assert!(info.field_at(1).unwrap().type_info().unwrap().is::<i32>());
2238        assert!(info.field_at(1).unwrap().is::<i32>());
2239
2240        // Tuple
2241        type MyTuple = (u32, f32, String);
2242
2243        let info = MyTuple::type_info().as_tuple().unwrap();
2244
2245        assert!(info.is::<MyTuple>());
2246        assert_eq!(MyTuple::type_path(), info.type_path());
2247        assert_eq!(f32::type_path(), info.field_at(1).unwrap().type_path());
2248        assert!(info.field_at(1).unwrap().type_info().unwrap().is::<f32>());
2249
2250        let value: &dyn Reflect = &(123_u32, 1.23_f32, String::from("Hello!"));
2251        let info = value.reflect_type_info();
2252        assert!(info.is::<MyTuple>());
2253
2254        // List
2255        type MyList = Vec<usize>;
2256
2257        let info = MyList::type_info().as_list().unwrap();
2258
2259        assert!(info.is::<MyList>());
2260        assert!(info.item_ty().is::<usize>());
2261        assert!(info.item_info().unwrap().is::<usize>());
2262        assert_eq!(MyList::type_path(), info.type_path());
2263        assert_eq!(usize::type_path(), info.item_ty().path());
2264
2265        let value: &dyn Reflect = &vec![123_usize];
2266        let info = value.reflect_type_info();
2267        assert!(info.is::<MyList>());
2268
2269        // List (SmallVec)
2270        #[cfg(feature = "smallvec")]
2271        {
2272            type MySmallVec = smallvec::SmallVec<[String; 2]>;
2273
2274            let info = MySmallVec::type_info().as_list().unwrap();
2275            assert!(info.is::<MySmallVec>());
2276            assert!(info.item_ty().is::<String>());
2277            assert!(info.item_info().unwrap().is::<String>());
2278            assert_eq!(MySmallVec::type_path(), info.type_path());
2279            assert_eq!(String::type_path(), info.item_ty().path());
2280
2281            let value: MySmallVec = smallvec::smallvec![String::default(); 2];
2282            let value: &dyn Reflect = &value;
2283            let info = value.reflect_type_info();
2284            assert!(info.is::<MySmallVec>());
2285        }
2286
2287        // Array
2288        type MyArray = [usize; 3];
2289
2290        let info = MyArray::type_info().as_array().unwrap();
2291        assert!(info.is::<MyArray>());
2292        assert!(info.item_ty().is::<usize>());
2293        assert!(info.item_info().unwrap().is::<usize>());
2294        assert_eq!(MyArray::type_path(), info.type_path());
2295        assert_eq!(usize::type_path(), info.item_ty().path());
2296        assert_eq!(3, info.capacity());
2297
2298        let value: &dyn Reflect = &[1usize, 2usize, 3usize];
2299        let info = value.reflect_type_info();
2300        assert!(info.is::<MyArray>());
2301
2302        // Cow<'static, str>
2303        type MyCowStr = Cow<'static, str>;
2304
2305        let info = MyCowStr::type_info().as_opaque().unwrap();
2306
2307        assert!(info.is::<MyCowStr>());
2308        assert_eq!(core::any::type_name::<MyCowStr>(), info.type_path());
2309
2310        let value: &dyn Reflect = &Cow::<'static, str>::Owned("Hello!".to_string());
2311        let info = value.reflect_type_info();
2312        assert!(info.is::<MyCowStr>());
2313
2314        // Cow<'static, [u8]>
2315        type MyCowSlice = Cow<'static, [u8]>;
2316
2317        let info = MyCowSlice::type_info().as_list().unwrap();
2318
2319        assert!(info.is::<MyCowSlice>());
2320        assert!(info.item_ty().is::<u8>());
2321        assert!(info.item_info().unwrap().is::<u8>());
2322        assert_eq!(core::any::type_name::<MyCowSlice>(), info.type_path());
2323        assert_eq!(core::any::type_name::<u8>(), info.item_ty().path());
2324
2325        let value: &dyn Reflect = &Cow::<'static, [u8]>::Owned(vec![0, 1, 2, 3]);
2326        let info = value.reflect_type_info();
2327        assert!(info.is::<MyCowSlice>());
2328
2329        // Map
2330        type MyMap = HashMap<usize, f32>;
2331
2332        let info = MyMap::type_info().as_map().unwrap();
2333
2334        assert!(info.is::<MyMap>());
2335        assert!(info.key_ty().is::<usize>());
2336        assert!(info.value_ty().is::<f32>());
2337        assert!(info.key_info().unwrap().is::<usize>());
2338        assert!(info.value_info().unwrap().is::<f32>());
2339        assert_eq!(MyMap::type_path(), info.type_path());
2340        assert_eq!(usize::type_path(), info.key_ty().path());
2341        assert_eq!(f32::type_path(), info.value_ty().path());
2342
2343        let value: &dyn Reflect = &MyMap::default();
2344        let info = value.reflect_type_info();
2345        assert!(info.is::<MyMap>());
2346
2347        // Value
2348        type MyValue = String;
2349
2350        let info = MyValue::type_info().as_opaque().unwrap();
2351
2352        assert!(info.is::<MyValue>());
2353        assert_eq!(MyValue::type_path(), info.type_path());
2354
2355        let value: &dyn Reflect = &String::from("Hello!");
2356        let info = value.reflect_type_info();
2357        assert!(info.is::<MyValue>());
2358    }
2359
2360    #[test]
2361    fn get_represented_kind_info() {
2362        #[derive(Reflect)]
2363        struct SomeStruct;
2364
2365        #[derive(Reflect)]
2366        struct SomeTupleStruct(f32);
2367
2368        #[derive(Reflect)]
2369        enum SomeEnum {
2370            Foo,
2371            Bar,
2372        }
2373
2374        let dyn_struct: &dyn Struct = &SomeStruct;
2375        let _: &StructInfo = dyn_struct.get_represented_struct_info().unwrap();
2376
2377        let dyn_map: &dyn Map = &HashMap::<(), ()>::default();
2378        let _: &MapInfo = dyn_map.get_represented_map_info().unwrap();
2379
2380        let dyn_array: &dyn Array = &[1, 2, 3];
2381        let _: &ArrayInfo = dyn_array.get_represented_array_info().unwrap();
2382
2383        let dyn_list: &dyn List = &vec![1, 2, 3];
2384        let _: &ListInfo = dyn_list.get_represented_list_info().unwrap();
2385
2386        let dyn_tuple_struct: &dyn TupleStruct = &SomeTupleStruct(5.0);
2387        let _: &TupleStructInfo = dyn_tuple_struct
2388            .get_represented_tuple_struct_info()
2389            .unwrap();
2390
2391        let dyn_enum: &dyn Enum = &SomeEnum::Foo;
2392        let _: &EnumInfo = dyn_enum.get_represented_enum_info().unwrap();
2393    }
2394
2395    #[test]
2396    fn should_permit_higher_ranked_lifetimes() {
2397        #[derive(Reflect)]
2398        #[reflect(from_reflect = false)]
2399        struct TestStruct {
2400            #[reflect(ignore)]
2401            _hrl: for<'a> fn(&'a str) -> &'a str,
2402        }
2403
2404        impl Default for TestStruct {
2405            fn default() -> Self {
2406                TestStruct {
2407                    _hrl: |input| input,
2408                }
2409            }
2410        }
2411
2412        fn get_type_registration<T: GetTypeRegistration>() {}
2413        get_type_registration::<TestStruct>();
2414    }
2415
2416    #[test]
2417    fn should_permit_valid_represented_type_for_dynamic() {
2418        let type_info = <[i32; 2] as Typed>::type_info();
2419        let mut dynamic_array = [123; 2].to_dynamic_array();
2420        dynamic_array.set_represented_type(Some(type_info));
2421    }
2422
2423    #[test]
2424    #[should_panic(expected = "expected TypeInfo::Array but received")]
2425    fn should_prohibit_invalid_represented_type_for_dynamic() {
2426        let type_info = <(i32, i32) as Typed>::type_info();
2427        let mut dynamic_array = [123; 2].to_dynamic_array();
2428        dynamic_array.set_represented_type(Some(type_info));
2429    }
2430
2431    #[cfg(feature = "documentation")]
2432    mod docstrings {
2433        use super::*;
2434
2435        #[test]
2436        fn should_not_contain_docs() {
2437            // Regular comments do not count as doc comments,
2438            // and are therefore not reflected.
2439            #[derive(Reflect)]
2440            struct SomeStruct;
2441
2442            let info = <SomeStruct as Typed>::type_info();
2443            assert_eq!(None, info.docs());
2444
2445            // Block comments do not count as doc comments,
2446            // and are therefore not reflected.
2447            #[derive(Reflect)]
2448            struct SomeOtherStruct;
2449
2450            let info = <SomeOtherStruct as Typed>::type_info();
2451            assert_eq!(None, info.docs());
2452        }
2453
2454        #[test]
2455        fn should_contain_docs() {
2456            /// Some struct.
2457            ///
2458            /// # Example
2459            ///
2460            /// ```ignore (This is only used for a unit test, no need to doc test)
2461            /// let some_struct = SomeStruct;
2462            /// ```
2463            #[derive(Reflect)]
2464            struct SomeStruct;
2465
2466            let info = <SomeStruct as Typed>::type_info();
2467            assert_eq!(
2468                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 ```"),
2469                info.docs()
2470            );
2471
2472            #[doc = "The compiler automatically converts `///`-style comments into `#[doc]` attributes."]
2473            #[doc = "Of course, you _could_ use the attribute directly if you wanted to."]
2474            #[doc = "Both will be reflected."]
2475            #[derive(Reflect)]
2476            struct SomeOtherStruct;
2477
2478            let info = <SomeOtherStruct as Typed>::type_info();
2479            assert_eq!(
2480                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."),
2481                info.docs()
2482            );
2483
2484            /// Some tuple struct.
2485            #[derive(Reflect)]
2486            struct SomeTupleStruct(usize);
2487
2488            let info = <SomeTupleStruct as Typed>::type_info();
2489            assert_eq!(Some(" Some tuple struct."), info.docs());
2490
2491            /// Some enum.
2492            #[derive(Reflect)]
2493            enum SomeEnum {
2494                Foo,
2495            }
2496
2497            let info = <SomeEnum as Typed>::type_info();
2498            assert_eq!(Some(" Some enum."), info.docs());
2499
2500            #[derive(Clone)]
2501            struct SomePrimitive;
2502            impl_reflect_opaque!(
2503                /// Some primitive for which we have attributed custom documentation.
2504                (in bevy_reflect::tests) SomePrimitive
2505            );
2506
2507            let info = <SomePrimitive as Typed>::type_info();
2508            assert_eq!(
2509                Some(" Some primitive for which we have attributed custom documentation."),
2510                info.docs()
2511            );
2512        }
2513
2514        #[test]
2515        fn fields_should_contain_docs() {
2516            #[derive(Reflect)]
2517            struct SomeStruct {
2518                /// The name
2519                name: String,
2520                /// The index
2521                index: usize,
2522                // Not documented...
2523                data: Vec<i32>,
2524            }
2525
2526            let info = <SomeStruct as Typed>::type_info().as_struct().unwrap();
2527
2528            let mut fields = info.iter();
2529            assert_eq!(Some(" The name"), fields.next().unwrap().docs());
2530            assert_eq!(Some(" The index"), fields.next().unwrap().docs());
2531            assert_eq!(None, fields.next().unwrap().docs());
2532        }
2533
2534        #[test]
2535        fn variants_should_contain_docs() {
2536            #[derive(Reflect)]
2537            enum SomeEnum {
2538                // Not documented...
2539                Nothing,
2540                /// Option A
2541                A(
2542                    /// Index
2543                    usize,
2544                ),
2545                /// Option B
2546                B {
2547                    /// Name
2548                    name: String,
2549                },
2550            }
2551
2552            let info = <SomeEnum as Typed>::type_info().as_enum().unwrap();
2553
2554            let mut variants = info.iter();
2555            assert_eq!(None, variants.next().unwrap().docs());
2556
2557            let variant = variants.next().unwrap().as_tuple_variant().unwrap();
2558            assert_eq!(Some(" Option A"), variant.docs());
2559            let field = variant.field_at(0).unwrap();
2560            assert_eq!(Some(" Index"), field.docs());
2561
2562            let variant = variants.next().unwrap().as_struct_variant().unwrap();
2563            assert_eq!(Some(" Option B"), variant.docs());
2564            let field = variant.field_at(0).unwrap();
2565            assert_eq!(Some(" Name"), field.docs());
2566        }
2567    }
2568
2569    #[test]
2570    fn into_reflect() {
2571        trait TestTrait: Reflect {}
2572
2573        #[derive(Reflect)]
2574        struct TestStruct;
2575
2576        impl TestTrait for TestStruct {}
2577
2578        let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
2579
2580        // Should compile:
2581        let _ = trait_object.into_reflect();
2582    }
2583
2584    #[test]
2585    fn as_reflect() {
2586        trait TestTrait: Reflect {}
2587
2588        #[derive(Reflect)]
2589        struct TestStruct;
2590
2591        impl TestTrait for TestStruct {}
2592
2593        let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
2594
2595        // Should compile:
2596        let _ = trait_object.as_reflect();
2597    }
2598
2599    #[test]
2600    fn should_reflect_debug() {
2601        #[derive(Reflect)]
2602        struct Test {
2603            value: usize,
2604            list: Vec<String>,
2605            array: [f32; 3],
2606            map: HashMap<i32, f32>,
2607            a_struct: SomeStruct,
2608            a_tuple_struct: SomeTupleStruct,
2609            enum_unit: SomeEnum,
2610            enum_tuple: SomeEnum,
2611            enum_struct: SomeEnum,
2612            custom: CustomDebug,
2613            #[reflect(ignore)]
2614            #[expect(dead_code, reason = "This value is intended to not be reflected.")]
2615            ignored: isize,
2616        }
2617
2618        #[derive(Reflect)]
2619        struct SomeStruct {
2620            foo: String,
2621        }
2622
2623        #[derive(Reflect)]
2624        enum SomeEnum {
2625            A,
2626            B(usize),
2627            C { value: i32 },
2628        }
2629
2630        #[derive(Reflect)]
2631        struct SomeTupleStruct(String);
2632
2633        #[derive(Reflect)]
2634        #[reflect(Debug)]
2635        struct CustomDebug;
2636        impl Debug for CustomDebug {
2637            fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
2638                f.write_str("Cool debug!")
2639            }
2640        }
2641
2642        let mut map = <HashMap<_, _>>::default();
2643        map.insert(123, 1.23);
2644
2645        let test = Test {
2646            value: 123,
2647            list: vec![String::from("A"), String::from("B"), String::from("C")],
2648            array: [1.0, 2.0, 3.0],
2649            map,
2650            a_struct: SomeStruct {
2651                foo: String::from("A Struct!"),
2652            },
2653            a_tuple_struct: SomeTupleStruct(String::from("A Tuple Struct!")),
2654            enum_unit: SomeEnum::A,
2655            enum_tuple: SomeEnum::B(123),
2656            enum_struct: SomeEnum::C { value: 321 },
2657            custom: CustomDebug,
2658            ignored: 321,
2659        };
2660
2661        let reflected: &dyn Reflect = &test;
2662        let expected = r#"
2663bevy_reflect::tests::Test {
2664    value: 123,
2665    list: [
2666        "A",
2667        "B",
2668        "C",
2669    ],
2670    array: [
2671        1.0,
2672        2.0,
2673        3.0,
2674    ],
2675    map: {
2676        123: 1.23,
2677    },
2678    a_struct: bevy_reflect::tests::SomeStruct {
2679        foo: "A Struct!",
2680    },
2681    a_tuple_struct: bevy_reflect::tests::SomeTupleStruct(
2682        "A Tuple Struct!",
2683    ),
2684    enum_unit: A,
2685    enum_tuple: B(
2686        123,
2687    ),
2688    enum_struct: C {
2689        value: 321,
2690    },
2691    custom: Cool debug!,
2692}"#;
2693
2694        assert_eq!(expected, format!("\n{reflected:#?}"));
2695    }
2696
2697    #[test]
2698    fn multiple_reflect_lists() {
2699        #[derive(Hash, PartialEq, Reflect)]
2700        #[reflect(Debug, Hash)]
2701        #[reflect(PartialEq)]
2702        struct Foo(i32);
2703
2704        impl Debug for Foo {
2705            fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
2706                write!(f, "Foo")
2707            }
2708        }
2709
2710        let foo = Foo(123);
2711        let foo: &dyn PartialReflect = &foo;
2712
2713        assert!(foo.reflect_hash().is_some());
2714        assert_eq!(Some(true), foo.reflect_partial_eq(foo));
2715        assert_eq!("Foo".to_string(), format!("{foo:?}"));
2716    }
2717
2718    #[test]
2719    fn custom_debug_function() {
2720        #[derive(Reflect)]
2721        #[reflect(Debug(custom_debug))]
2722        struct Foo {
2723            a: u32,
2724        }
2725
2726        fn custom_debug(_x: &Foo, f: &mut Formatter<'_>) -> core::fmt::Result {
2727            write!(f, "123")
2728        }
2729
2730        let foo = Foo { a: 1 };
2731        let foo: &dyn Reflect = &foo;
2732
2733        assert_eq!("123", format!("{foo:?}"));
2734    }
2735
2736    #[test]
2737    fn should_allow_custom_where() {
2738        #[derive(Reflect)]
2739        #[reflect(where T: Default)]
2740        struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
2741
2742        #[derive(Default, TypePath)]
2743        struct Bar;
2744
2745        #[derive(TypePath)]
2746        struct Baz;
2747
2748        assert_impl_all!(Foo<Bar>: Reflect);
2749        assert_not_impl_all!(Foo<Baz>: Reflect);
2750    }
2751
2752    #[test]
2753    fn should_allow_empty_custom_where() {
2754        #[derive(Reflect)]
2755        #[reflect(where)]
2756        struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
2757
2758        #[derive(TypePath)]
2759        struct Bar;
2760
2761        assert_impl_all!(Foo<Bar>: Reflect);
2762    }
2763
2764    #[test]
2765    fn should_allow_multiple_custom_where() {
2766        #[derive(Reflect)]
2767        #[reflect(where T: Default)]
2768        #[reflect(where U: core::ops::Add<T>)]
2769        struct Foo<T, U>(T, U);
2770
2771        #[allow(
2772            clippy::allow_attributes,
2773            dead_code,
2774            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
2775        )]
2776        #[derive(Reflect)]
2777        struct Baz {
2778            a: Foo<i32, i32>,
2779            b: Foo<u32, u32>,
2780        }
2781
2782        assert_impl_all!(Foo<i32, i32>: Reflect);
2783        assert_not_impl_all!(Foo<i32, usize>: Reflect);
2784    }
2785
2786    #[test]
2787    fn should_allow_custom_where_with_assoc_type() {
2788        trait Trait {
2789            type Assoc;
2790        }
2791
2792        // We don't need `T` to be `Reflect` since we only care about `T::Assoc`
2793        #[derive(Reflect)]
2794        #[reflect(where T::Assoc: core::fmt::Display)]
2795        struct Foo<T: Trait>(T::Assoc);
2796
2797        #[derive(TypePath)]
2798        struct Bar;
2799
2800        impl Trait for Bar {
2801            type Assoc = usize;
2802        }
2803
2804        #[derive(TypePath)]
2805        struct Baz;
2806
2807        impl Trait for Baz {
2808            type Assoc = (f32, f32);
2809        }
2810
2811        assert_impl_all!(Foo<Bar>: Reflect);
2812        assert_not_impl_all!(Foo<Baz>: Reflect);
2813    }
2814
2815    #[test]
2816    fn should_allow_empty_enums() {
2817        #[derive(Reflect)]
2818        enum Empty {}
2819
2820        assert_impl_all!(Empty: Reflect);
2821    }
2822
2823    #[test]
2824    fn recursive_typed_storage_does_not_hang() {
2825        #[derive(Reflect)]
2826        struct Recurse<T>(T);
2827
2828        let _ = <Recurse<Recurse<()>> as Typed>::type_info();
2829        let _ = <Recurse<Recurse<()>> as TypePath>::type_path();
2830
2831        #[derive(Reflect)]
2832        #[reflect(no_field_bounds)]
2833        struct SelfRecurse {
2834            recurse: Vec<SelfRecurse>,
2835        }
2836
2837        let _ = <SelfRecurse as Typed>::type_info();
2838        let _ = <SelfRecurse as TypePath>::type_path();
2839
2840        #[derive(Reflect)]
2841        #[reflect(no_field_bounds)]
2842        enum RecurseA {
2843            Recurse(RecurseB),
2844        }
2845
2846        #[derive(Reflect)]
2847        // `#[reflect(no_field_bounds)]` not needed since already added to `RecurseA`
2848        struct RecurseB {
2849            vector: Vec<RecurseA>,
2850        }
2851
2852        let _ = <RecurseA as Typed>::type_info();
2853        let _ = <RecurseA as TypePath>::type_path();
2854        let _ = <RecurseB as Typed>::type_info();
2855        let _ = <RecurseB as TypePath>::type_path();
2856    }
2857
2858    #[test]
2859    fn recursive_registration_does_not_hang() {
2860        #[derive(Reflect)]
2861        struct Recurse<T>(T);
2862
2863        let mut registry = TypeRegistry::empty();
2864
2865        registry.register::<Recurse<Recurse<()>>>();
2866
2867        #[derive(Reflect)]
2868        #[reflect(no_field_bounds)]
2869        struct SelfRecurse {
2870            recurse: Vec<SelfRecurse>,
2871        }
2872
2873        registry.register::<SelfRecurse>();
2874
2875        #[derive(Reflect)]
2876        #[reflect(no_field_bounds)]
2877        enum RecurseA {
2878            Recurse(RecurseB),
2879        }
2880
2881        #[derive(Reflect)]
2882        struct RecurseB {
2883            vector: Vec<RecurseA>,
2884        }
2885
2886        registry.register::<RecurseA>();
2887        assert!(registry.contains(TypeId::of::<RecurseA>()));
2888        assert!(registry.contains(TypeId::of::<RecurseB>()));
2889    }
2890
2891    #[test]
2892    fn can_opt_out_type_path() {
2893        #[derive(Reflect)]
2894        #[reflect(type_path = false)]
2895        struct Foo<T> {
2896            #[reflect(ignore)]
2897            _marker: PhantomData<T>,
2898        }
2899
2900        struct NotTypePath;
2901
2902        impl<T: 'static> TypePath for Foo<T> {
2903            fn type_path() -> &'static str {
2904                core::any::type_name::<Self>()
2905            }
2906
2907            fn short_type_path() -> &'static str {
2908                static CELL: GenericTypePathCell = GenericTypePathCell::new();
2909                CELL.get_or_insert::<Self, _>(|| ShortName::of::<Self>().to_string())
2910            }
2911
2912            fn type_ident() -> Option<&'static str> {
2913                Some("Foo")
2914            }
2915
2916            fn crate_name() -> Option<&'static str> {
2917                Some("bevy_reflect")
2918            }
2919
2920            fn module_path() -> Option<&'static str> {
2921                Some("bevy_reflect::tests")
2922            }
2923        }
2924
2925        // Can use `TypePath`
2926        let path = <Foo<NotTypePath> as TypePath>::type_path();
2927        assert_eq!("bevy_reflect::tests::can_opt_out_type_path::Foo<bevy_reflect::tests::can_opt_out_type_path::NotTypePath>", path);
2928
2929        // Can register the type
2930        let mut registry = TypeRegistry::default();
2931        registry.register::<Foo<NotTypePath>>();
2932
2933        let registration = registry.get(TypeId::of::<Foo<NotTypePath>>()).unwrap();
2934        assert_eq!(
2935            "Foo<NotTypePath>",
2936            registration.type_info().type_path_table().short_path()
2937        );
2938    }
2939
2940    #[test]
2941    fn dynamic_types_debug_format() {
2942        #[derive(Debug, Reflect)]
2943        struct TestTupleStruct(u32);
2944
2945        #[derive(Debug, Reflect)]
2946        enum TestEnum {
2947            A(u32),
2948            B,
2949        }
2950
2951        #[derive(Debug, Reflect)]
2952        // test DynamicStruct
2953        struct TestStruct {
2954            // test DynamicTuple
2955            tuple: (u32, u32),
2956            // test DynamicTupleStruct
2957            tuple_struct: TestTupleStruct,
2958            // test DynamicList
2959            list: Vec<u32>,
2960            // test DynamicArray
2961            array: [u32; 3],
2962            // test DynamicEnum
2963            e: TestEnum,
2964            // test DynamicMap
2965            map: HashMap<u32, u32>,
2966            // test reflected value
2967            value: u32,
2968        }
2969        let mut map = <HashMap<_, _>>::default();
2970        map.insert(9, 10);
2971        let mut test_struct: DynamicStruct = TestStruct {
2972            tuple: (0, 1),
2973            list: vec![2, 3, 4],
2974            array: [5, 6, 7],
2975            tuple_struct: TestTupleStruct(8),
2976            e: TestEnum::A(11),
2977            map,
2978            value: 12,
2979        }
2980        .to_dynamic_struct();
2981
2982        // test unknown DynamicStruct
2983        let mut test_unknown_struct = DynamicStruct::default();
2984        test_unknown_struct.insert("a", 13);
2985        test_struct.insert("unknown_struct", test_unknown_struct);
2986        // test unknown DynamicTupleStruct
2987        let mut test_unknown_tuple_struct = DynamicTupleStruct::default();
2988        test_unknown_tuple_struct.insert(14);
2989        test_struct.insert("unknown_tuplestruct", test_unknown_tuple_struct);
2990        assert_eq!(
2991            format!("{test_struct:?}"),
2992            "DynamicStruct(bevy_reflect::tests::TestStruct { \
2993                tuple: DynamicTuple((0, 1)), \
2994                tuple_struct: DynamicTupleStruct(bevy_reflect::tests::TestTupleStruct(8)), \
2995                list: DynamicList([2, 3, 4]), \
2996                array: DynamicArray([5, 6, 7]), \
2997                e: DynamicEnum(A(11)), \
2998                map: DynamicMap({9: 10}), \
2999                value: 12, \
3000                unknown_struct: DynamicStruct(_ { a: 13 }), \
3001                unknown_tuplestruct: DynamicTupleStruct(_(14)) \
3002            })"
3003        );
3004    }
3005
3006    #[test]
3007    fn assert_impl_reflect_macro_on_all() {
3008        struct Struct {
3009            foo: (),
3010        }
3011        struct TupleStruct(());
3012        enum Enum {
3013            Foo { foo: () },
3014            Bar(()),
3015        }
3016
3017        impl_reflect!(
3018            #[type_path = "my_crate::foo"]
3019            struct Struct {
3020                foo: (),
3021            }
3022        );
3023
3024        impl_reflect!(
3025            #[type_path = "my_crate::foo"]
3026            struct TupleStruct(());
3027        );
3028
3029        impl_reflect!(
3030            #[type_path = "my_crate::foo"]
3031            enum Enum {
3032                Foo { foo: () },
3033                Bar(()),
3034            }
3035        );
3036
3037        assert_impl_all!(Struct: Reflect);
3038        assert_impl_all!(TupleStruct: Reflect);
3039        assert_impl_all!(Enum: Reflect);
3040    }
3041
3042    #[test]
3043    fn should_reflect_remote_type() {
3044        mod external_crate {
3045            use alloc::string::String;
3046
3047            #[derive(Debug, Default)]
3048            pub struct TheirType {
3049                pub value: String,
3050            }
3051        }
3052
3053        // === Remote Wrapper === //
3054        #[reflect_remote(external_crate::TheirType)]
3055        #[derive(Debug, Default)]
3056        #[reflect(Debug, Default)]
3057        struct MyType {
3058            pub value: String,
3059        }
3060
3061        let mut patch = DynamicStruct::default();
3062        patch.set_represented_type(Some(MyType::type_info()));
3063        patch.insert("value", "Goodbye".to_string());
3064
3065        let mut data = MyType(external_crate::TheirType {
3066            value: "Hello".to_string(),
3067        });
3068
3069        assert_eq!("Hello", data.0.value);
3070        data.apply(&patch);
3071        assert_eq!("Goodbye", data.0.value);
3072
3073        // === Struct Container === //
3074        #[derive(Reflect, Debug)]
3075        #[reflect(from_reflect = false)]
3076        struct ContainerStruct {
3077            #[reflect(remote = MyType)]
3078            their_type: external_crate::TheirType,
3079        }
3080
3081        let mut patch = DynamicStruct::default();
3082        patch.set_represented_type(Some(ContainerStruct::type_info()));
3083        patch.insert(
3084            "their_type",
3085            MyType(external_crate::TheirType {
3086                value: "Goodbye".to_string(),
3087            }),
3088        );
3089
3090        let mut data = ContainerStruct {
3091            their_type: external_crate::TheirType {
3092                value: "Hello".to_string(),
3093            },
3094        };
3095
3096        assert_eq!("Hello", data.their_type.value);
3097        data.apply(&patch);
3098        assert_eq!("Goodbye", data.their_type.value);
3099
3100        // === Tuple Struct Container === //
3101        #[derive(Reflect, Debug)]
3102        struct ContainerTupleStruct(#[reflect(remote = MyType)] external_crate::TheirType);
3103
3104        let mut patch = DynamicTupleStruct::default();
3105        patch.set_represented_type(Some(ContainerTupleStruct::type_info()));
3106        patch.insert(MyType(external_crate::TheirType {
3107            value: "Goodbye".to_string(),
3108        }));
3109
3110        let mut data = ContainerTupleStruct(external_crate::TheirType {
3111            value: "Hello".to_string(),
3112        });
3113
3114        assert_eq!("Hello", data.0.value);
3115        data.apply(&patch);
3116        assert_eq!("Goodbye", data.0.value);
3117    }
3118
3119    #[test]
3120    fn should_reflect_remote_value_type() {
3121        mod external_crate {
3122            use alloc::string::String;
3123
3124            #[derive(Clone, Debug, Default)]
3125            pub struct TheirType {
3126                pub value: String,
3127            }
3128        }
3129
3130        // === Remote Wrapper === //
3131        #[reflect_remote(external_crate::TheirType)]
3132        #[derive(Clone, Debug, Default)]
3133        #[reflect(opaque)]
3134        #[reflect(Debug, Default)]
3135        struct MyType {
3136            pub value: String,
3137        }
3138
3139        let mut data = MyType(external_crate::TheirType {
3140            value: "Hello".to_string(),
3141        });
3142
3143        let patch = MyType(external_crate::TheirType {
3144            value: "Goodbye".to_string(),
3145        });
3146
3147        assert_eq!("Hello", data.0.value);
3148        data.apply(&patch);
3149        assert_eq!("Goodbye", data.0.value);
3150
3151        // === Struct Container === //
3152        #[derive(Reflect, Debug)]
3153        #[reflect(from_reflect = false)]
3154        struct ContainerStruct {
3155            #[reflect(remote = MyType)]
3156            their_type: external_crate::TheirType,
3157        }
3158
3159        let mut patch = DynamicStruct::default();
3160        patch.set_represented_type(Some(ContainerStruct::type_info()));
3161        patch.insert(
3162            "their_type",
3163            MyType(external_crate::TheirType {
3164                value: "Goodbye".to_string(),
3165            }),
3166        );
3167
3168        let mut data = ContainerStruct {
3169            their_type: external_crate::TheirType {
3170                value: "Hello".to_string(),
3171            },
3172        };
3173
3174        assert_eq!("Hello", data.their_type.value);
3175        data.apply(&patch);
3176        assert_eq!("Goodbye", data.their_type.value);
3177
3178        // === Tuple Struct Container === //
3179        #[derive(Reflect, Debug)]
3180        struct ContainerTupleStruct(#[reflect(remote = MyType)] external_crate::TheirType);
3181
3182        let mut patch = DynamicTupleStruct::default();
3183        patch.set_represented_type(Some(ContainerTupleStruct::type_info()));
3184        patch.insert(MyType(external_crate::TheirType {
3185            value: "Goodbye".to_string(),
3186        }));
3187
3188        let mut data = ContainerTupleStruct(external_crate::TheirType {
3189            value: "Hello".to_string(),
3190        });
3191
3192        assert_eq!("Hello", data.0.value);
3193        data.apply(&patch);
3194        assert_eq!("Goodbye", data.0.value);
3195    }
3196
3197    #[test]
3198    fn should_reflect_remote_type_from_module() {
3199        mod wrapper {
3200            use super::*;
3201
3202            // We have to place this module internally to this one to get around the following error:
3203            // ```
3204            // error[E0433]: failed to resolve: use of undeclared crate or module `external_crate`
3205            // ```
3206            pub mod external_crate {
3207                use alloc::string::String;
3208
3209                #[allow(
3210                    clippy::allow_attributes,
3211                    dead_code,
3212                    reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
3213                )]
3214                pub struct TheirType {
3215                    pub value: String,
3216                }
3217            }
3218
3219            #[reflect_remote(external_crate::TheirType)]
3220            pub struct MyType {
3221                pub value: String,
3222            }
3223        }
3224
3225        #[allow(
3226            clippy::allow_attributes,
3227            dead_code,
3228            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
3229        )]
3230        #[derive(Reflect)]
3231        struct ContainerStruct {
3232            #[reflect(remote = wrapper::MyType)]
3233            their_type: wrapper::external_crate::TheirType,
3234        }
3235    }
3236
3237    #[test]
3238    fn should_reflect_remote_enum() {
3239        mod external_crate {
3240            use alloc::string::String;
3241
3242            #[derive(Debug, PartialEq, Eq)]
3243            pub enum TheirType {
3244                Unit,
3245                Tuple(usize),
3246                Struct { value: String },
3247            }
3248        }
3249
3250        // === Remote Wrapper === //
3251        #[reflect_remote(external_crate::TheirType)]
3252        #[derive(Debug)]
3253        #[reflect(Debug)]
3254        enum MyType {
3255            Unit,
3256            Tuple(usize),
3257            Struct { value: String },
3258        }
3259
3260        let mut patch = DynamicEnum::from(MyType(external_crate::TheirType::Tuple(123)));
3261
3262        let mut data = MyType(external_crate::TheirType::Unit);
3263
3264        assert_eq!(external_crate::TheirType::Unit, data.0);
3265        data.apply(&patch);
3266        assert_eq!(external_crate::TheirType::Tuple(123), data.0);
3267
3268        patch = DynamicEnum::from(MyType(external_crate::TheirType::Struct {
3269            value: "Hello world!".to_string(),
3270        }));
3271
3272        data.apply(&patch);
3273        assert_eq!(
3274            external_crate::TheirType::Struct {
3275                value: "Hello world!".to_string()
3276            },
3277            data.0
3278        );
3279
3280        // === Enum Container === //
3281        #[derive(Reflect, Debug, PartialEq)]
3282        enum ContainerEnum {
3283            Foo,
3284            Bar {
3285                #[reflect(remote = MyType)]
3286                their_type: external_crate::TheirType,
3287            },
3288        }
3289
3290        let patch = DynamicEnum::from(ContainerEnum::Bar {
3291            their_type: external_crate::TheirType::Tuple(123),
3292        });
3293
3294        let mut data = ContainerEnum::Foo;
3295
3296        assert_eq!(ContainerEnum::Foo, data);
3297        data.apply(&patch);
3298        assert_eq!(
3299            ContainerEnum::Bar {
3300                their_type: external_crate::TheirType::Tuple(123)
3301            },
3302            data
3303        );
3304    }
3305
3306    #[test]
3307    fn should_reflect_nested_remote_type() {
3308        mod external_crate {
3309            pub struct TheirOuter<T> {
3310                pub a: TheirInner<T>,
3311                pub b: TheirInner<bool>,
3312            }
3313
3314            pub struct TheirInner<T>(pub T);
3315        }
3316
3317        #[reflect_remote(external_crate::TheirOuter<T>)]
3318        struct MyOuter<T: FromReflect + Reflectable> {
3319            #[reflect(remote = MyInner<T>)]
3320            pub a: external_crate::TheirInner<T>,
3321            #[reflect(remote = MyInner<bool>)]
3322            pub b: external_crate::TheirInner<bool>,
3323        }
3324
3325        #[reflect_remote(external_crate::TheirInner<T>)]
3326        struct MyInner<T: FromReflect>(pub T);
3327
3328        let mut patch = DynamicStruct::default();
3329        patch.set_represented_type(Some(MyOuter::<i32>::type_info()));
3330        patch.insert("a", MyInner(external_crate::TheirInner(321_i32)));
3331        patch.insert("b", MyInner(external_crate::TheirInner(true)));
3332
3333        let mut data = MyOuter(external_crate::TheirOuter {
3334            a: external_crate::TheirInner(123_i32),
3335            b: external_crate::TheirInner(false),
3336        });
3337
3338        assert_eq!(123, data.0.a.0);
3339        assert!(!data.0.b.0);
3340        data.apply(&patch);
3341        assert_eq!(321, data.0.a.0);
3342        assert!(data.0.b.0);
3343    }
3344
3345    #[test]
3346    fn should_reflect_nested_remote_enum() {
3347        mod external_crate {
3348            use core::fmt::Debug;
3349
3350            #[derive(Debug)]
3351            pub enum TheirOuter<T: Debug> {
3352                Unit,
3353                Tuple(TheirInner<T>),
3354                Struct { value: TheirInner<T> },
3355            }
3356            #[derive(Debug)]
3357            pub enum TheirInner<T: Debug> {
3358                Unit,
3359                Tuple(T),
3360                Struct { value: T },
3361            }
3362        }
3363
3364        #[reflect_remote(external_crate::TheirOuter<T>)]
3365        #[derive(Debug)]
3366        enum MyOuter<T: FromReflect + Reflectable + Debug> {
3367            Unit,
3368            Tuple(#[reflect(remote = MyInner<T>)] external_crate::TheirInner<T>),
3369            Struct {
3370                #[reflect(remote = MyInner<T>)]
3371                value: external_crate::TheirInner<T>,
3372            },
3373        }
3374
3375        #[reflect_remote(external_crate::TheirInner<T>)]
3376        #[derive(Debug)]
3377        enum MyInner<T: FromReflect + Debug> {
3378            Unit,
3379            Tuple(T),
3380            Struct { value: T },
3381        }
3382
3383        let mut patch = DynamicEnum::default();
3384        let mut value = DynamicStruct::default();
3385        value.insert("value", MyInner(external_crate::TheirInner::Tuple(123)));
3386        patch.set_variant("Struct", value);
3387
3388        let mut data = MyOuter(external_crate::TheirOuter::<i32>::Unit);
3389
3390        assert!(matches!(
3391            data,
3392            MyOuter(external_crate::TheirOuter::<i32>::Unit)
3393        ));
3394        data.apply(&patch);
3395        assert!(matches!(
3396            data,
3397            MyOuter(external_crate::TheirOuter::Struct {
3398                value: external_crate::TheirInner::Tuple(123)
3399            })
3400        ));
3401    }
3402
3403    #[test]
3404    fn should_take_remote_type() {
3405        mod external_crate {
3406            use alloc::string::String;
3407
3408            #[derive(Debug, Default, PartialEq, Eq)]
3409            pub struct TheirType {
3410                pub value: String,
3411            }
3412        }
3413
3414        // === Remote Wrapper === //
3415        #[reflect_remote(external_crate::TheirType)]
3416        #[derive(Debug, Default)]
3417        #[reflect(Debug, Default)]
3418        struct MyType {
3419            pub value: String,
3420        }
3421
3422        let input: Box<dyn Reflect> = Box::new(MyType(external_crate::TheirType {
3423            value: "Hello".to_string(),
3424        }));
3425
3426        let output: external_crate::TheirType = input
3427            .take()
3428            .expect("should downcast to `external_crate::TheirType`");
3429        assert_eq!(
3430            external_crate::TheirType {
3431                value: "Hello".to_string(),
3432            },
3433            output
3434        );
3435    }
3436
3437    #[test]
3438    fn should_try_take_remote_type() {
3439        mod external_crate {
3440            use alloc::string::String;
3441
3442            #[derive(Debug, Default, PartialEq, Eq)]
3443            pub struct TheirType {
3444                pub value: String,
3445            }
3446        }
3447
3448        // === Remote Wrapper === //
3449        #[reflect_remote(external_crate::TheirType)]
3450        #[derive(Debug, Default)]
3451        #[reflect(Debug, Default)]
3452        struct MyType {
3453            pub value: String,
3454        }
3455
3456        let input: Box<dyn PartialReflect> = Box::new(MyType(external_crate::TheirType {
3457            value: "Hello".to_string(),
3458        }));
3459
3460        let output: external_crate::TheirType = input
3461            .try_take()
3462            .expect("should downcast to `external_crate::TheirType`");
3463        assert_eq!(
3464            external_crate::TheirType {
3465                value: "Hello".to_string(),
3466            },
3467            output,
3468        );
3469    }
3470
3471    #[test]
3472    fn should_take_nested_remote_type() {
3473        mod external_crate {
3474            #[derive(PartialEq, Eq, Debug)]
3475            pub struct TheirOuter<T> {
3476                pub inner: TheirInner<T>,
3477            }
3478            #[derive(PartialEq, Eq, Debug)]
3479            pub struct TheirInner<T>(pub T);
3480        }
3481
3482        #[reflect_remote(external_crate::TheirOuter<T>)]
3483        struct MyOuter<T: FromReflect + Reflectable> {
3484            #[reflect(remote = MyInner<T>)]
3485            pub inner: external_crate::TheirInner<T>,
3486        }
3487
3488        #[reflect_remote(external_crate::TheirInner<T>)]
3489        struct MyInner<T: FromReflect>(pub T);
3490
3491        let input: Box<dyn Reflect> = Box::new(MyOuter(external_crate::TheirOuter {
3492            inner: external_crate::TheirInner(123),
3493        }));
3494
3495        let output: external_crate::TheirOuter<i32> = input
3496            .take()
3497            .expect("should downcast to `external_crate::TheirOuter`");
3498        assert_eq!(
3499            external_crate::TheirOuter {
3500                inner: external_crate::TheirInner(123),
3501            },
3502            output
3503        );
3504    }
3505
3506    // https://github.com/bevyengine/bevy/issues/19017
3507    #[test]
3508    fn should_serialize_opaque_remote_type() {
3509        mod external_crate {
3510            use serde::{Deserialize, Serialize};
3511            #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
3512            pub struct Vector2<T>(pub [T; 2]);
3513        }
3514
3515        #[reflect_remote(external_crate::Vector2<i32>)]
3516        #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
3517        #[reflect(Serialize, Deserialize)]
3518        #[reflect(opaque)]
3519        struct Vector2Wrapper([i32; 2]);
3520
3521        #[derive(Reflect, Debug, PartialEq)]
3522        struct Point(#[reflect(remote = Vector2Wrapper)] external_crate::Vector2<i32>);
3523
3524        let point = Point(external_crate::Vector2([1, 2]));
3525
3526        let mut registry = TypeRegistry::new();
3527        registry.register::<Point>();
3528        registry.register::<Vector2Wrapper>();
3529
3530        let serializer = ReflectSerializer::new(&point, &registry);
3531        let serialized = ron::to_string(&serializer).unwrap();
3532        assert_eq!(serialized, r#"{"bevy_reflect::tests::Point":((((1,2))))}"#);
3533
3534        let mut deserializer = Deserializer::from_str(&serialized).unwrap();
3535        let reflect_deserializer = ReflectDeserializer::new(&registry);
3536        let deserialized = reflect_deserializer.deserialize(&mut deserializer).unwrap();
3537        let point = <Point as FromReflect>::from_reflect(&*deserialized).unwrap();
3538        assert_eq!(point, Point(external_crate::Vector2([1, 2])));
3539    }
3540
3541    #[cfg(feature = "auto_register")]
3542    mod auto_register_reflect {
3543        use super::*;
3544
3545        #[test]
3546        fn should_ignore_auto_reflect_registration() {
3547            #[derive(Reflect)]
3548            #[reflect(no_auto_register)]
3549            struct NoAutomaticStruct {
3550                a: usize,
3551            }
3552
3553            let mut registry = TypeRegistry::default();
3554            registry.register_derived_types();
3555
3556            assert!(!registry.contains(TypeId::of::<NoAutomaticStruct>()));
3557        }
3558
3559        #[test]
3560        fn should_auto_register_reflect_for_all_supported_types() {
3561            // Struct
3562            #[derive(Reflect)]
3563            struct StructReflect {
3564                a: usize,
3565            }
3566
3567            // ZST struct
3568            #[derive(Reflect)]
3569            struct ZSTStructReflect;
3570
3571            // Tuple struct
3572            #[derive(Reflect)]
3573            struct TupleStructReflect(pub u32);
3574
3575            // Enum
3576            #[derive(Reflect)]
3577            enum EnumReflect {
3578                A,
3579                B,
3580            }
3581
3582            // ZST enum
3583            #[derive(Reflect)]
3584            enum ZSTEnumReflect {}
3585
3586            // Opaque struct
3587            #[derive(Reflect, Clone)]
3588            #[reflect(opaque)]
3589            struct OpaqueStructReflect {
3590                _a: usize,
3591            }
3592
3593            // ZST opaque struct
3594            #[derive(Reflect, Clone)]
3595            #[reflect(opaque)]
3596            struct ZSTOpaqueStructReflect;
3597
3598            let mut registry = TypeRegistry::default();
3599            registry.register_derived_types();
3600
3601            assert!(registry.contains(TypeId::of::<StructReflect>()));
3602            assert!(registry.contains(TypeId::of::<ZSTStructReflect>()));
3603            assert!(registry.contains(TypeId::of::<TupleStructReflect>()));
3604            assert!(registry.contains(TypeId::of::<EnumReflect>()));
3605            assert!(registry.contains(TypeId::of::<ZSTEnumReflect>()));
3606            assert!(registry.contains(TypeId::of::<OpaqueStructReflect>()));
3607            assert!(registry.contains(TypeId::of::<ZSTOpaqueStructReflect>()));
3608        }
3609    }
3610
3611    #[cfg(feature = "glam")]
3612    mod glam {
3613        use super::*;
3614        use ::glam::{quat, vec3, Quat, Vec3};
3615
3616        #[test]
3617        fn quat_serialization() {
3618            let q = quat(1.0, 2.0, 3.0, 4.0);
3619
3620            let mut registry = TypeRegistry::default();
3621            registry.register::<f32>();
3622            registry.register::<Quat>();
3623
3624            let ser = ReflectSerializer::new(&q, &registry);
3625
3626            let config = PrettyConfig::default()
3627                .new_line(String::from("\n"))
3628                .indentor(String::from("    "));
3629            let output = to_string_pretty(&ser, config).unwrap();
3630            let expected = r#"
3631{
3632    "glam::Quat": (1.0, 2.0, 3.0, 4.0),
3633}"#;
3634
3635            assert_eq!(expected, format!("\n{output}"));
3636        }
3637
3638        #[test]
3639        fn quat_deserialization() {
3640            let data = r#"
3641{
3642    "glam::Quat": (1.0, 2.0, 3.0, 4.0),
3643}"#;
3644
3645            let mut registry = TypeRegistry::default();
3646            registry.register::<Quat>();
3647            registry.register::<f32>();
3648
3649            let de = ReflectDeserializer::new(&registry);
3650
3651            let mut deserializer =
3652                Deserializer::from_str(data).expect("Failed to acquire deserializer");
3653
3654            let dynamic_struct = de
3655                .deserialize(&mut deserializer)
3656                .expect("Failed to deserialize");
3657
3658            let mut result = Quat::default();
3659
3660            result.apply(dynamic_struct.as_partial_reflect());
3661
3662            assert_eq!(result, quat(1.0, 2.0, 3.0, 4.0));
3663        }
3664
3665        #[test]
3666        fn vec3_serialization() {
3667            let v = vec3(12.0, 3.0, -6.9);
3668
3669            let mut registry = TypeRegistry::default();
3670            registry.register::<f32>();
3671            registry.register::<Vec3>();
3672
3673            let ser = ReflectSerializer::new(&v, &registry);
3674
3675            let config = PrettyConfig::default()
3676                .new_line(String::from("\n"))
3677                .indentor(String::from("    "));
3678            let output = to_string_pretty(&ser, config).unwrap();
3679            let expected = r#"
3680{
3681    "glam::Vec3": (12.0, 3.0, -6.9),
3682}"#;
3683
3684            assert_eq!(expected, format!("\n{output}"));
3685        }
3686
3687        #[test]
3688        fn vec3_deserialization() {
3689            let data = r#"
3690{
3691    "glam::Vec3": (12.0, 3.0, -6.9),
3692}"#;
3693
3694            let mut registry = TypeRegistry::default();
3695            registry.add_registration(Vec3::get_type_registration());
3696            registry.add_registration(f32::get_type_registration());
3697
3698            let de = ReflectDeserializer::new(&registry);
3699
3700            let mut deserializer =
3701                Deserializer::from_str(data).expect("Failed to acquire deserializer");
3702
3703            let dynamic_struct = de
3704                .deserialize(&mut deserializer)
3705                .expect("Failed to deserialize");
3706
3707            let mut result = Vec3::default();
3708
3709            result.apply(dynamic_struct.as_partial_reflect());
3710
3711            assert_eq!(result, vec3(12.0, 3.0, -6.9));
3712        }
3713
3714        #[test]
3715        fn vec3_field_access() {
3716            let mut v = vec3(1.0, 2.0, 3.0);
3717
3718            assert_eq!(*v.get_field::<f32>("x").unwrap(), 1.0);
3719
3720            *v.get_field_mut::<f32>("y").unwrap() = 6.0;
3721
3722            assert_eq!(v.y, 6.0);
3723        }
3724
3725        #[test]
3726        fn vec3_path_access() {
3727            let mut v = vec3(1.0, 2.0, 3.0);
3728
3729            assert_eq!(
3730                *v.reflect_path("x")
3731                    .unwrap()
3732                    .try_downcast_ref::<f32>()
3733                    .unwrap(),
3734                1.0
3735            );
3736
3737            *v.reflect_path_mut("y")
3738                .unwrap()
3739                .try_downcast_mut::<f32>()
3740                .unwrap() = 6.0;
3741
3742            assert_eq!(v.y, 6.0);
3743        }
3744
3745        #[test]
3746        fn vec3_apply_dynamic() {
3747            let mut v = vec3(3.0, 3.0, 3.0);
3748
3749            let mut d = DynamicStruct::default();
3750            d.insert("x", 4.0f32);
3751            d.insert("y", 2.0f32);
3752            d.insert("z", 1.0f32);
3753
3754            v.apply(&d);
3755
3756            assert_eq!(v, vec3(4.0, 2.0, 1.0));
3757        }
3758    }
3759}