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`], [`indexmap`], [`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`], [`indexmap`], 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//! [`indexmap`]: https://docs.rs/indexmap/latest/indexmap/
563//! [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.
564//! [`bevy_reflect_derive/documentation`]: bevy_reflect_derive
565//! [`bevy_reflect_derive/functions`]: bevy_reflect_derive
566//! [`DynamicFunction`]: crate::func::DynamicFunction
567//! [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut
568//! [`ArgList`]: crate::func::ArgList
569//! [derive `Reflect`]: derive@crate::Reflect
570
571#![no_std]
572
573#[cfg(feature = "std")]
574extern crate std;
575
576extern crate alloc;
577
578// Required to make proc macros work in bevy itself.
579extern crate self as bevy_reflect;
580
581mod array;
582mod error;
583mod fields;
584mod from_reflect;
585#[cfg(feature = "functions")]
586pub mod func;
587mod is;
588mod kind;
589mod list;
590mod map;
591mod path;
592mod reflect;
593mod reflectable;
594mod remote;
595mod set;
596mod struct_trait;
597mod tuple;
598mod tuple_struct;
599mod type_info;
600mod type_path;
601mod type_registry;
602
603mod impls {
604    mod alloc;
605    mod bevy_platform;
606    mod core;
607    mod foldhash;
608    #[cfg(feature = "hashbrown")]
609    mod hashbrown;
610    mod macros;
611    #[cfg(feature = "std")]
612    mod std;
613
614    #[cfg(feature = "glam")]
615    mod glam;
616    #[cfg(feature = "indexmap")]
617    mod indexmap;
618    #[cfg(feature = "petgraph")]
619    mod petgraph;
620    #[cfg(feature = "smallvec")]
621    mod smallvec;
622    #[cfg(feature = "smol_str")]
623    mod smol_str;
624    #[cfg(feature = "uuid")]
625    mod uuid;
626    #[cfg(feature = "wgpu-types")]
627    mod wgpu_types;
628}
629
630pub mod attributes;
631mod enums;
632mod generics;
633pub mod serde;
634pub mod std_traits;
635#[cfg(feature = "debug_stack")]
636mod type_info_stack;
637pub mod utility;
638
639/// The reflect prelude.
640///
641/// This includes the most common types in this crate, re-exported for your convenience.
642pub mod prelude {
643    pub use crate::std_traits::*;
644
645    #[doc(hidden)]
646    pub use crate::{
647        reflect_trait, FromReflect, GetField, GetPath, GetTupleStructField, PartialReflect,
648        Reflect, ReflectDeserialize, ReflectFromReflect, ReflectPath, ReflectSerialize, Struct,
649        TupleStruct, TypePath,
650    };
651
652    #[cfg(feature = "functions")]
653    pub use crate::func::{Function, IntoFunction, IntoFunctionMut};
654}
655
656pub use array::*;
657pub use enums::*;
658pub use error::*;
659pub use fields::*;
660pub use from_reflect::*;
661pub use generics::*;
662pub use is::*;
663pub use kind::*;
664pub use list::*;
665pub use map::*;
666pub use path::*;
667pub use reflect::*;
668pub use reflectable::*;
669pub use remote::*;
670pub use set::*;
671pub use struct_trait::*;
672pub use tuple::*;
673pub use tuple_struct::*;
674pub use type_info::*;
675pub use type_path::*;
676pub use type_registry::*;
677
678pub use bevy_reflect_derive::*;
679pub use erased_serde;
680
681/// Exports used by the reflection macros.
682///
683/// These are not meant to be used directly and are subject to breaking changes.
684#[doc(hidden)]
685pub mod __macro_exports {
686    use crate::{
687        DynamicArray, DynamicEnum, DynamicList, DynamicMap, DynamicStruct, DynamicTuple,
688        DynamicTupleStruct, GetTypeRegistration, TypeRegistry,
689    };
690
691    /// Re-exports of items from the [`alloc`] crate.
692    ///
693    /// This is required because in `std` environments (e.g., the `std` feature is enabled)
694    /// the `alloc` crate may not have been included, making its namespace unreliable.
695    pub mod alloc_utils {
696        pub use ::alloc::{
697            borrow::{Cow, ToOwned},
698            boxed::Box,
699            string::ToString,
700        };
701    }
702
703    /// A wrapper trait around [`GetTypeRegistration`].
704    ///
705    /// This trait is used by the derive macro to recursively register all type dependencies.
706    /// It's used instead of `GetTypeRegistration` directly to avoid making dynamic types also
707    /// implement `GetTypeRegistration` in order to be used as active fields.
708    ///
709    /// This trait has a blanket implementation for all types that implement `GetTypeRegistration`
710    /// and manual implementations for all dynamic types (which simply do nothing).
711    #[diagnostic::on_unimplemented(
712        message = "`{Self}` does not implement `GetTypeRegistration` so cannot be registered for reflection",
713        note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
714    )]
715    pub trait RegisterForReflection {
716        #[expect(
717            unused_variables,
718            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."
719        )]
720        fn __register(registry: &mut TypeRegistry) {}
721    }
722
723    impl<T: GetTypeRegistration> RegisterForReflection for T {
724        fn __register(registry: &mut TypeRegistry) {
725            registry.register::<T>();
726        }
727    }
728
729    impl RegisterForReflection for DynamicEnum {}
730
731    impl RegisterForReflection for DynamicTupleStruct {}
732
733    impl RegisterForReflection for DynamicStruct {}
734
735    impl RegisterForReflection for DynamicMap {}
736
737    impl RegisterForReflection for DynamicList {}
738
739    impl RegisterForReflection for DynamicArray {}
740
741    impl RegisterForReflection for DynamicTuple {}
742
743    /// Automatic reflect registration implementation
744    #[cfg(feature = "auto_register")]
745    pub mod auto_register {
746        pub use super::*;
747
748        #[cfg(all(
749            not(feature = "auto_register_inventory"),
750            not(feature = "auto_register_static")
751        ))]
752        compile_error!(
753            "Choosing a backend is required for automatic reflect registration. Please enable either the \"auto_register_inventory\" or the \"auto_register_static\" feature."
754        );
755
756        /// inventory impl
757        #[cfg(all(
758            not(feature = "auto_register_static"),
759            feature = "auto_register_inventory"
760        ))]
761        mod __automatic_type_registration_impl {
762            use super::*;
763
764            pub use inventory;
765
766            /// Stores type registration functions
767            pub struct AutomaticReflectRegistrations(pub fn(&mut TypeRegistry));
768
769            /// Registers all collected types.
770            pub fn register_types(registry: &mut TypeRegistry) {
771                #[cfg(target_family = "wasm")]
772                wasm_support::init();
773                for registration_fn in inventory::iter::<AutomaticReflectRegistrations> {
774                    registration_fn.0(registry);
775                }
776            }
777
778            inventory::collect!(AutomaticReflectRegistrations);
779
780            #[cfg(target_family = "wasm")]
781            mod wasm_support {
782                use bevy_platform::sync::atomic::{AtomicBool, Ordering};
783
784                static INIT_DONE: AtomicBool = AtomicBool::new(false);
785
786                #[expect(unsafe_code, reason = "This function is generated by linker.")]
787                unsafe extern "C" {
788                    fn __wasm_call_ctors();
789                }
790
791                /// This function must be called before using [`inventory::iter`] on [`AutomaticReflectRegistrations`] to run constructors on all platforms.
792                pub fn init() {
793                    if INIT_DONE.swap(true, Ordering::Relaxed) {
794                        return;
795                    };
796                    // SAFETY:
797                    // This will call constructors on wasm platforms at most once (as long as `init` is the only function that calls `__wasm_call_ctors`).
798                    //
799                    // For more information see: https://docs.rs/inventory/latest/inventory/#webassembly-and-constructors
800                    #[expect(
801                        unsafe_code,
802                        reason = "This function must be called to use inventory on wasm."
803                    )]
804                    unsafe {
805                        __wasm_call_ctors();
806                    }
807                }
808            }
809        }
810
811        /// static impl
812        #[cfg(feature = "auto_register_static")]
813        mod __automatic_type_registration_impl {
814            use super::*;
815            use alloc::vec::Vec;
816            use bevy_platform::sync::Mutex;
817
818            static REGISTRATION_FNS: Mutex<Vec<fn(&mut TypeRegistry)>> = Mutex::new(Vec::new());
819
820            /// Adds a new registration function for [`TypeRegistry`]
821            pub fn push_registration_fn(registration_fn: fn(&mut TypeRegistry)) {
822                REGISTRATION_FNS.lock().unwrap().push(registration_fn);
823            }
824
825            /// Registers all collected types.
826            pub fn register_types(registry: &mut TypeRegistry) {
827                for func in REGISTRATION_FNS.lock().unwrap().iter() {
828                    (func)(registry);
829                }
830            }
831        }
832
833        #[cfg(any(feature = "auto_register_static", feature = "auto_register_inventory"))]
834        pub use __automatic_type_registration_impl::*;
835    }
836}
837
838#[cfg(test)]
839#[expect(
840    clippy::approx_constant,
841    reason = "We don't need the exact value of Pi here."
842)]
843mod tests {
844    use ::serde::{de::DeserializeSeed, Deserialize, Serialize};
845    use alloc::{
846        borrow::Cow,
847        boxed::Box,
848        format,
849        string::{String, ToString},
850        vec,
851        vec::Vec,
852    };
853    use bevy_platform::collections::HashMap;
854    use core::{
855        any::TypeId,
856        fmt::{Debug, Formatter},
857        hash::Hash,
858        marker::PhantomData,
859    };
860    use disqualified::ShortName;
861    use ron::{
862        ser::{to_string_pretty, PrettyConfig},
863        Deserializer,
864    };
865    use static_assertions::{assert_impl_all, assert_not_impl_all};
866
867    use super::{prelude::*, *};
868    use crate::{
869        serde::{ReflectDeserializer, ReflectSerializer},
870        utility::GenericTypePathCell,
871    };
872
873    #[test]
874    fn try_apply_should_detect_kinds() {
875        #[derive(Reflect, Debug)]
876        struct Struct {
877            a: u32,
878            b: f32,
879        }
880
881        #[derive(Reflect, Debug)]
882        enum Enum {
883            A,
884            B(u32),
885        }
886
887        let mut struct_target = Struct {
888            a: 0xDEADBEEF,
889            b: 3.14,
890        };
891
892        let mut enum_target = Enum::A;
893
894        let array_src = [8, 0, 8];
895
896        let result = struct_target.try_apply(&enum_target);
897        assert!(
898            matches!(
899                result,
900                Err(ApplyError::MismatchedKinds {
901                    from_kind: ReflectKind::Enum,
902                    to_kind: ReflectKind::Struct
903                })
904            ),
905            "result was {result:?}"
906        );
907
908        let result = enum_target.try_apply(&array_src);
909        assert!(
910            matches!(
911                result,
912                Err(ApplyError::MismatchedKinds {
913                    from_kind: ReflectKind::Array,
914                    to_kind: ReflectKind::Enum
915                })
916            ),
917            "result was {result:?}"
918        );
919    }
920
921    #[test]
922    fn reflect_struct() {
923        #[derive(Reflect)]
924        struct Foo {
925            a: u32,
926            b: f32,
927            c: Bar,
928        }
929        #[derive(Reflect)]
930        struct Bar {
931            x: u32,
932        }
933
934        let mut foo = Foo {
935            a: 42,
936            b: 3.14,
937            c: Bar { x: 1 },
938        };
939
940        let a = *foo.get_field::<u32>("a").unwrap();
941        assert_eq!(a, 42);
942
943        *foo.get_field_mut::<u32>("a").unwrap() += 1;
944        assert_eq!(foo.a, 43);
945
946        let bar = foo.get_field::<Bar>("c").unwrap();
947        assert_eq!(bar.x, 1);
948
949        // nested retrieval
950        let c = foo.field("c").unwrap();
951        let value = c.reflect_ref().as_struct().unwrap();
952        assert_eq!(*value.get_field::<u32>("x").unwrap(), 1);
953
954        // patch Foo with a dynamic struct
955        let mut dynamic_struct = DynamicStruct::default();
956        dynamic_struct.insert("a", 123u32);
957        dynamic_struct.insert("should_be_ignored", 456);
958
959        foo.apply(&dynamic_struct);
960        assert_eq!(foo.a, 123);
961    }
962
963    #[test]
964    fn reflect_map() {
965        #[derive(Reflect, Hash)]
966        #[reflect(Hash)]
967        struct Foo {
968            a: u32,
969            b: String,
970        }
971
972        let key_a = Foo {
973            a: 1,
974            b: "k1".to_string(),
975        };
976
977        let key_b = Foo {
978            a: 1,
979            b: "k1".to_string(),
980        };
981
982        let key_c = Foo {
983            a: 3,
984            b: "k3".to_string(),
985        };
986
987        let mut map = DynamicMap::default();
988        map.insert(key_a, 10u32);
989        assert_eq!(
990            10,
991            *map.get(&key_b).unwrap().try_downcast_ref::<u32>().unwrap()
992        );
993        assert!(map.get(&key_c).is_none());
994        *map.get_mut(&key_b)
995            .unwrap()
996            .try_downcast_mut::<u32>()
997            .unwrap() = 20;
998        assert_eq!(
999            20,
1000            *map.get(&key_b).unwrap().try_downcast_ref::<u32>().unwrap()
1001        );
1002    }
1003
1004    #[test]
1005    fn reflect_unit_struct() {
1006        #[derive(Reflect)]
1007        struct Foo(u32, u64);
1008
1009        let mut foo = Foo(1, 2);
1010        assert_eq!(1, *foo.get_field::<u32>(0).unwrap());
1011        assert_eq!(2, *foo.get_field::<u64>(1).unwrap());
1012
1013        let mut patch = DynamicTupleStruct::default();
1014        patch.insert(3u32);
1015        patch.insert(4u64);
1016        assert_eq!(
1017            3,
1018            *patch.field(0).unwrap().try_downcast_ref::<u32>().unwrap()
1019        );
1020        assert_eq!(
1021            4,
1022            *patch.field(1).unwrap().try_downcast_ref::<u64>().unwrap()
1023        );
1024
1025        foo.apply(&patch);
1026        assert_eq!(3, foo.0);
1027        assert_eq!(4, foo.1);
1028
1029        let mut iter = patch.iter_fields();
1030        assert_eq!(3, *iter.next().unwrap().try_downcast_ref::<u32>().unwrap());
1031        assert_eq!(4, *iter.next().unwrap().try_downcast_ref::<u64>().unwrap());
1032    }
1033
1034    #[test]
1035    #[should_panic(
1036        expected = "the given key of type `bevy_reflect::tests::Foo` does not support hashing"
1037    )]
1038    fn reflect_map_no_hash() {
1039        #[derive(Reflect)]
1040        struct Foo {
1041            a: u32,
1042        }
1043
1044        let foo = Foo { a: 1 };
1045        assert!(foo.reflect_hash().is_none());
1046
1047        let mut map = DynamicMap::default();
1048        map.insert(foo, 10u32);
1049    }
1050
1051    #[test]
1052    #[should_panic(
1053        expected = "the dynamic type `bevy_reflect::DynamicStruct` (representing `bevy_reflect::tests::Foo`) does not support hashing"
1054    )]
1055    fn reflect_map_no_hash_dynamic_representing() {
1056        #[derive(Reflect, Hash)]
1057        #[reflect(Hash)]
1058        struct Foo {
1059            a: u32,
1060        }
1061
1062        let foo = Foo { a: 1 };
1063        assert!(foo.reflect_hash().is_some());
1064        let dynamic = foo.to_dynamic_struct();
1065
1066        let mut map = DynamicMap::default();
1067        map.insert(dynamic, 11u32);
1068    }
1069
1070    #[test]
1071    #[should_panic(
1072        expected = "the dynamic type `bevy_reflect::DynamicStruct` does not support hashing"
1073    )]
1074    fn reflect_map_no_hash_dynamic() {
1075        #[allow(
1076            clippy::allow_attributes,
1077            dead_code,
1078            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1079        )]
1080        #[derive(Reflect, Hash)]
1081        #[reflect(Hash)]
1082        struct Foo {
1083            a: u32,
1084        }
1085
1086        let mut dynamic = DynamicStruct::default();
1087        dynamic.insert("a", 4u32);
1088        assert!(dynamic.reflect_hash().is_none());
1089
1090        let mut map = DynamicMap::default();
1091        map.insert(dynamic, 11u32);
1092    }
1093
1094    #[test]
1095    fn reflect_ignore() {
1096        #[derive(Reflect)]
1097        struct Foo {
1098            a: u32,
1099            #[reflect(ignore)]
1100            _b: u32,
1101        }
1102
1103        let foo = Foo { a: 1, _b: 2 };
1104
1105        let values: Vec<u32> = foo
1106            .iter_fields()
1107            .map(|value| *value.try_downcast_ref::<u32>().unwrap())
1108            .collect();
1109        assert_eq!(values, vec![1]);
1110    }
1111
1112    /// This test ensures that we are able to reflect generic types with one or more type parameters.
1113    ///
1114    /// When there is an `Add` implementation for `String`, the compiler isn't able to infer the correct
1115    /// type to deref to.
1116    /// If we don't append the strings in the `TypePath` derive correctly (i.e. explicitly specifying the type),
1117    /// we'll get a compilation error saying that "`&String` cannot be added to `String`".
1118    ///
1119    /// So this test just ensures that we do that correctly.
1120    ///
1121    /// This problem is a known issue and is unexpectedly expected behavior:
1122    /// - <https://github.com/rust-lang/rust/issues/77143>
1123    /// - <https://github.com/bodil/smartstring/issues/7>
1124    /// - <https://github.com/pola-rs/polars/issues/14666>
1125    #[test]
1126    fn should_reflect_generic() {
1127        struct FakeString {}
1128
1129        // This implementation confuses the compiler when trying to add a `&String` to a `String`
1130        impl core::ops::Add<FakeString> for String {
1131            type Output = Self;
1132            fn add(self, _rhs: FakeString) -> Self::Output {
1133                unreachable!()
1134            }
1135        }
1136
1137        #[expect(
1138            dead_code,
1139            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1140        )]
1141        #[derive(Reflect)]
1142        struct Foo<A>(A);
1143
1144        #[expect(
1145            dead_code,
1146            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1147        )]
1148        #[derive(Reflect)]
1149        struct Bar<A, B>(A, B);
1150
1151        #[expect(
1152            dead_code,
1153            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1154        )]
1155        #[derive(Reflect)]
1156        struct Baz<A, B, C>(A, B, C);
1157    }
1158
1159    #[test]
1160    fn should_reflect_clone() {
1161        // Struct
1162        #[derive(Reflect, Debug, PartialEq)]
1163        struct Foo(usize);
1164
1165        let value = Foo(123);
1166        let clone = value.reflect_clone().expect("should reflect_clone struct");
1167        assert_eq!(value, clone.take::<Foo>().unwrap());
1168
1169        // Tuple
1170        let foo = (123, 4.56);
1171        let clone = foo.reflect_clone().expect("should reflect_clone tuple");
1172        assert_eq!(foo, clone.take::<(u32, f32)>().unwrap());
1173    }
1174
1175    #[test]
1176    fn should_reflect_clone_generic_type() {
1177        #[derive(Reflect, Debug, PartialEq)]
1178        struct Foo<T, U>(T, #[reflect(ignore, clone)] PhantomData<U>);
1179        #[derive(TypePath, Debug, PartialEq)]
1180        struct Bar;
1181
1182        // `usize` will be cloned via `Reflect::reflect_clone`
1183        // `PhantomData<Bar>` will be cloned via `Clone::clone`
1184        let value = Foo::<usize, Bar>(123, PhantomData);
1185        let clone = value
1186            .reflect_clone()
1187            .expect("should reflect_clone generic struct");
1188        assert_eq!(value, clone.take::<Foo<usize, Bar>>().unwrap());
1189    }
1190
1191    #[test]
1192    fn should_reflect_clone_with_clone() {
1193        // A custom clone function to verify that the `#[reflect(Clone)]` container attribute
1194        // takes precedence over the `#[reflect(clone)]` field attribute.
1195        #[expect(
1196            dead_code,
1197            reason = "if things are working correctly, this function should never be called"
1198        )]
1199        fn custom_clone(_value: &usize) -> usize {
1200            panic!("should not be called");
1201        }
1202
1203        // Tuple Struct
1204        #[derive(Reflect, Clone, Debug, PartialEq)]
1205        #[reflect(Clone)]
1206        struct Foo(#[reflect(clone = "custom_clone")] usize);
1207
1208        let value = Foo(123);
1209        let clone = value
1210            .reflect_clone()
1211            .expect("should reflect_clone tuple struct");
1212        assert_eq!(value, clone.take::<Foo>().unwrap());
1213
1214        // Struct
1215        #[derive(Reflect, Clone, Debug, PartialEq)]
1216        #[reflect(Clone)]
1217        struct Bar {
1218            #[reflect(clone = "custom_clone")]
1219            value: usize,
1220        }
1221
1222        let value = Bar { value: 123 };
1223        let clone = value.reflect_clone().expect("should reflect_clone struct");
1224        assert_eq!(value, clone.take::<Bar>().unwrap());
1225
1226        // Enum
1227        #[derive(Reflect, Clone, Debug, PartialEq)]
1228        #[reflect(Clone)]
1229        enum Baz {
1230            Unit,
1231            Tuple(#[reflect(clone = "custom_clone")] usize),
1232            Struct {
1233                #[reflect(clone = "custom_clone")]
1234                value: usize,
1235            },
1236        }
1237
1238        let value = Baz::Unit;
1239        let clone = value
1240            .reflect_clone()
1241            .expect("should reflect_clone unit variant");
1242        assert_eq!(value, clone.take::<Baz>().unwrap());
1243
1244        let value = Baz::Tuple(123);
1245        let clone = value
1246            .reflect_clone()
1247            .expect("should reflect_clone tuple variant");
1248        assert_eq!(value, clone.take::<Baz>().unwrap());
1249
1250        let value = Baz::Struct { value: 123 };
1251        let clone = value
1252            .reflect_clone()
1253            .expect("should reflect_clone struct variant");
1254        assert_eq!(value, clone.take::<Baz>().unwrap());
1255    }
1256
1257    #[test]
1258    fn should_custom_reflect_clone() {
1259        #[derive(Reflect, Debug, PartialEq)]
1260        #[reflect(Clone(clone_foo))]
1261        struct Foo(usize);
1262
1263        fn clone_foo(foo: &Foo) -> Foo {
1264            Foo(foo.0 + 198)
1265        }
1266
1267        let foo = Foo(123);
1268        let clone = foo.reflect_clone().unwrap();
1269        assert_eq!(Foo(321), clone.take::<Foo>().unwrap());
1270    }
1271
1272    #[test]
1273    fn should_not_clone_ignored_fields() {
1274        // Tuple Struct
1275        #[derive(Reflect, Clone, Debug, PartialEq)]
1276        struct Foo(#[reflect(ignore)] usize);
1277
1278        let foo = Foo(123);
1279        let clone = foo.reflect_clone();
1280        assert_eq!(
1281            clone.unwrap_err(),
1282            ReflectCloneError::FieldNotCloneable {
1283                field: FieldId::Unnamed(0),
1284                variant: None,
1285                container_type_path: Cow::Borrowed(Foo::type_path()),
1286            }
1287        );
1288
1289        // Struct
1290        #[derive(Reflect, Clone, Debug, PartialEq)]
1291        struct Bar {
1292            #[reflect(ignore)]
1293            value: usize,
1294        }
1295
1296        let bar = Bar { value: 123 };
1297        let clone = bar.reflect_clone();
1298        assert_eq!(
1299            clone.unwrap_err(),
1300            ReflectCloneError::FieldNotCloneable {
1301                field: FieldId::Named(Cow::Borrowed("value")),
1302                variant: None,
1303                container_type_path: Cow::Borrowed(Bar::type_path()),
1304            }
1305        );
1306
1307        // Enum
1308        #[derive(Reflect, Clone, Debug, PartialEq)]
1309        enum Baz {
1310            Tuple(#[reflect(ignore)] usize),
1311            Struct {
1312                #[reflect(ignore)]
1313                value: usize,
1314            },
1315        }
1316
1317        let baz = Baz::Tuple(123);
1318        let clone = baz.reflect_clone();
1319        assert_eq!(
1320            clone.unwrap_err(),
1321            ReflectCloneError::FieldNotCloneable {
1322                field: FieldId::Unnamed(0),
1323                variant: Some(Cow::Borrowed("Tuple")),
1324                container_type_path: Cow::Borrowed(Baz::type_path()),
1325            }
1326        );
1327
1328        let baz = Baz::Struct { value: 123 };
1329        let clone = baz.reflect_clone();
1330        assert_eq!(
1331            clone.unwrap_err(),
1332            ReflectCloneError::FieldNotCloneable {
1333                field: FieldId::Named(Cow::Borrowed("value")),
1334                variant: Some(Cow::Borrowed("Struct")),
1335                container_type_path: Cow::Borrowed(Baz::type_path()),
1336            }
1337        );
1338    }
1339
1340    #[test]
1341    fn should_clone_ignored_fields_with_clone_attributes() {
1342        #[derive(Reflect, Clone, Debug, PartialEq)]
1343        struct Foo(#[reflect(ignore, clone)] usize);
1344
1345        let foo = Foo(123);
1346        let clone = foo.reflect_clone().unwrap();
1347        assert_eq!(Foo(123), clone.take::<Foo>().unwrap());
1348
1349        #[derive(Reflect, Clone, Debug, PartialEq)]
1350        struct Bar(#[reflect(ignore, clone = "clone_usize")] usize);
1351
1352        fn clone_usize(this: &usize) -> usize {
1353            *this + 198
1354        }
1355
1356        let bar = Bar(123);
1357        let clone = bar.reflect_clone().unwrap();
1358        assert_eq!(Bar(321), clone.take::<Bar>().unwrap());
1359    }
1360
1361    #[test]
1362    fn should_composite_reflect_clone() {
1363        #[derive(Reflect, Debug, PartialEq)]
1364        enum MyEnum {
1365            Unit,
1366            Tuple(
1367                Foo,
1368                #[reflect(ignore, clone)] Bar,
1369                #[reflect(clone = "clone_baz")] Baz,
1370            ),
1371            Struct {
1372                foo: Foo,
1373                #[reflect(ignore, clone)]
1374                bar: Bar,
1375                #[reflect(clone = "clone_baz")]
1376                baz: Baz,
1377            },
1378        }
1379
1380        #[derive(Reflect, Debug, PartialEq)]
1381        struct Foo {
1382            #[reflect(clone = "clone_bar")]
1383            bar: Bar,
1384            baz: Baz,
1385        }
1386
1387        #[derive(Reflect, Default, Clone, Debug, PartialEq)]
1388        #[reflect(Clone)]
1389        struct Bar(String);
1390
1391        #[derive(Reflect, Debug, PartialEq)]
1392        struct Baz(String);
1393
1394        fn clone_bar(bar: &Bar) -> Bar {
1395            Bar(format!("{}!", bar.0))
1396        }
1397
1398        fn clone_baz(baz: &Baz) -> Baz {
1399            Baz(format!("{}!", baz.0))
1400        }
1401
1402        let my_enum = MyEnum::Unit;
1403        let clone = my_enum.reflect_clone().unwrap();
1404        assert_eq!(MyEnum::Unit, clone.take::<MyEnum>().unwrap());
1405
1406        let my_enum = MyEnum::Tuple(
1407            Foo {
1408                bar: Bar("bar".to_string()),
1409                baz: Baz("baz".to_string()),
1410            },
1411            Bar("bar".to_string()),
1412            Baz("baz".to_string()),
1413        );
1414        let clone = my_enum.reflect_clone().unwrap();
1415        assert_eq!(
1416            MyEnum::Tuple(
1417                Foo {
1418                    bar: Bar("bar!".to_string()),
1419                    baz: Baz("baz".to_string()),
1420                },
1421                Bar("bar".to_string()),
1422                Baz("baz!".to_string()),
1423            ),
1424            clone.take::<MyEnum>().unwrap()
1425        );
1426
1427        let my_enum = MyEnum::Struct {
1428            foo: Foo {
1429                bar: Bar("bar".to_string()),
1430                baz: Baz("baz".to_string()),
1431            },
1432            bar: Bar("bar".to_string()),
1433            baz: Baz("baz".to_string()),
1434        };
1435        let clone = my_enum.reflect_clone().unwrap();
1436        assert_eq!(
1437            MyEnum::Struct {
1438                foo: Foo {
1439                    bar: Bar("bar!".to_string()),
1440                    baz: Baz("baz".to_string()),
1441                },
1442                bar: Bar("bar".to_string()),
1443                baz: Baz("baz!".to_string()),
1444            },
1445            clone.take::<MyEnum>().unwrap()
1446        );
1447    }
1448
1449    #[test]
1450    fn should_call_from_reflect_dynamically() {
1451        #[derive(Reflect)]
1452        struct MyStruct {
1453            foo: usize,
1454        }
1455
1456        // Register
1457        let mut registry = TypeRegistry::default();
1458        registry.register::<MyStruct>();
1459
1460        // Get type data
1461        let type_id = TypeId::of::<MyStruct>();
1462        let rfr = registry
1463            .get_type_data::<ReflectFromReflect>(type_id)
1464            .expect("the FromReflect trait should be registered");
1465
1466        // Call from_reflect
1467        let mut dynamic_struct = DynamicStruct::default();
1468        dynamic_struct.insert("foo", 123usize);
1469        let reflected = rfr
1470            .from_reflect(&dynamic_struct)
1471            .expect("the type should be properly reflected");
1472
1473        // Assert
1474        let expected = MyStruct { foo: 123 };
1475        assert!(expected
1476            .reflect_partial_eq(reflected.as_partial_reflect())
1477            .unwrap_or_default());
1478        let not_expected = MyStruct { foo: 321 };
1479        assert!(!not_expected
1480            .reflect_partial_eq(reflected.as_partial_reflect())
1481            .unwrap_or_default());
1482    }
1483
1484    #[test]
1485    fn from_reflect_should_allow_ignored_unnamed_fields() {
1486        #[derive(Reflect, Eq, PartialEq, Debug)]
1487        struct MyTupleStruct(i8, #[reflect(ignore)] i16, i32);
1488
1489        let expected = MyTupleStruct(1, 0, 3);
1490
1491        let mut dyn_tuple_struct = DynamicTupleStruct::default();
1492        dyn_tuple_struct.insert(1_i8);
1493        dyn_tuple_struct.insert(3_i32);
1494        let my_tuple_struct = <MyTupleStruct as FromReflect>::from_reflect(&dyn_tuple_struct);
1495
1496        assert_eq!(Some(expected), my_tuple_struct);
1497
1498        #[derive(Reflect, Eq, PartialEq, Debug)]
1499        enum MyEnum {
1500            Tuple(i8, #[reflect(ignore)] i16, i32),
1501        }
1502
1503        let expected = MyEnum::Tuple(1, 0, 3);
1504
1505        let mut dyn_tuple = DynamicTuple::default();
1506        dyn_tuple.insert(1_i8);
1507        dyn_tuple.insert(3_i32);
1508
1509        let mut dyn_enum = DynamicEnum::default();
1510        dyn_enum.set_variant("Tuple", dyn_tuple);
1511
1512        let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
1513
1514        assert_eq!(Some(expected), my_enum);
1515    }
1516
1517    #[test]
1518    fn from_reflect_should_use_default_field_attributes() {
1519        #[derive(Reflect, Eq, PartialEq, Debug)]
1520        struct MyStruct {
1521            // Use `Default::default()`
1522            // Note that this isn't an ignored field
1523            #[reflect(default)]
1524            foo: String,
1525
1526            // Use `get_bar_default()`
1527            #[reflect(ignore)]
1528            #[reflect(default = "get_bar_default")]
1529            bar: NotReflect,
1530
1531            // Ensure attributes can be combined
1532            #[reflect(ignore, default = "get_bar_default")]
1533            baz: NotReflect,
1534        }
1535
1536        #[derive(Eq, PartialEq, Debug)]
1537        struct NotReflect(usize);
1538
1539        fn get_bar_default() -> NotReflect {
1540            NotReflect(123)
1541        }
1542
1543        let expected = MyStruct {
1544            foo: String::default(),
1545            bar: NotReflect(123),
1546            baz: NotReflect(123),
1547        };
1548
1549        let dyn_struct = DynamicStruct::default();
1550        let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
1551
1552        assert_eq!(Some(expected), my_struct);
1553    }
1554
1555    #[test]
1556    fn from_reflect_should_use_default_variant_field_attributes() {
1557        #[derive(Reflect, Eq, PartialEq, Debug)]
1558        enum MyEnum {
1559            Foo(#[reflect(default)] String),
1560            Bar {
1561                #[reflect(default = "get_baz_default")]
1562                #[reflect(ignore)]
1563                baz: usize,
1564            },
1565        }
1566
1567        fn get_baz_default() -> usize {
1568            123
1569        }
1570
1571        let expected = MyEnum::Foo(String::default());
1572
1573        let dyn_enum = DynamicEnum::new("Foo", DynamicTuple::default());
1574        let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
1575
1576        assert_eq!(Some(expected), my_enum);
1577
1578        let expected = MyEnum::Bar {
1579            baz: get_baz_default(),
1580        };
1581
1582        let dyn_enum = DynamicEnum::new("Bar", DynamicStruct::default());
1583        let my_enum = <MyEnum as FromReflect>::from_reflect(&dyn_enum);
1584
1585        assert_eq!(Some(expected), my_enum);
1586    }
1587
1588    #[test]
1589    fn from_reflect_should_use_default_container_attribute() {
1590        #[derive(Reflect, Eq, PartialEq, Debug)]
1591        #[reflect(Default)]
1592        struct MyStruct {
1593            foo: String,
1594            #[reflect(ignore)]
1595            bar: usize,
1596        }
1597
1598        impl Default for MyStruct {
1599            fn default() -> Self {
1600                Self {
1601                    foo: String::from("Hello"),
1602                    bar: 123,
1603                }
1604            }
1605        }
1606
1607        let expected = MyStruct {
1608            foo: String::from("Hello"),
1609            bar: 123,
1610        };
1611
1612        let dyn_struct = DynamicStruct::default();
1613        let my_struct = <MyStruct as FromReflect>::from_reflect(&dyn_struct);
1614
1615        assert_eq!(Some(expected), my_struct);
1616    }
1617
1618    #[test]
1619    fn reflect_complex_patch() {
1620        #[derive(Reflect, Eq, PartialEq, Debug)]
1621        #[reflect(PartialEq)]
1622        struct Foo {
1623            a: u32,
1624            #[reflect(ignore)]
1625            _b: u32,
1626            c: Vec<isize>,
1627            d: HashMap<usize, i8>,
1628            e: Bar,
1629            f: (i32, Vec<isize>, Bar),
1630            g: Vec<(Baz, HashMap<usize, Bar>)>,
1631            h: [u32; 2],
1632        }
1633
1634        #[derive(Reflect, Eq, PartialEq, Clone, Debug)]
1635        #[reflect(PartialEq)]
1636        struct Bar {
1637            x: u32,
1638        }
1639
1640        #[derive(Reflect, Eq, PartialEq, Debug)]
1641        struct Baz(String);
1642
1643        let mut hash_map = <HashMap<_, _>>::default();
1644        hash_map.insert(1, 1);
1645        hash_map.insert(2, 2);
1646
1647        let mut hash_map_baz = <HashMap<_, _>>::default();
1648        hash_map_baz.insert(1, Bar { x: 0 });
1649
1650        let mut foo = Foo {
1651            a: 1,
1652            _b: 1,
1653            c: vec![1, 2],
1654            d: hash_map,
1655            e: Bar { x: 1 },
1656            f: (1, vec![1, 2], Bar { x: 1 }),
1657            g: vec![(Baz("string".to_string()), hash_map_baz)],
1658            h: [2; 2],
1659        };
1660
1661        let mut foo_patch = DynamicStruct::default();
1662        foo_patch.insert("a", 2u32);
1663        foo_patch.insert("b", 2u32); // this should be ignored
1664
1665        let mut list = DynamicList::default();
1666        list.push(3isize);
1667        list.push(4isize);
1668        list.push(5isize);
1669        foo_patch.insert("c", list.to_dynamic_list());
1670
1671        let mut map = DynamicMap::default();
1672        map.insert(2usize, 3i8);
1673        map.insert(3usize, 4i8);
1674        foo_patch.insert("d", map);
1675
1676        let mut bar_patch = DynamicStruct::default();
1677        bar_patch.insert("x", 2u32);
1678        foo_patch.insert("e", bar_patch.to_dynamic_struct());
1679
1680        let mut tuple = DynamicTuple::default();
1681        tuple.insert(2i32);
1682        tuple.insert(list);
1683        tuple.insert(bar_patch);
1684        foo_patch.insert("f", tuple);
1685
1686        let mut composite = DynamicList::default();
1687        composite.push({
1688            let mut tuple = DynamicTuple::default();
1689            tuple.insert({
1690                let mut tuple_struct = DynamicTupleStruct::default();
1691                tuple_struct.insert("new_string".to_string());
1692                tuple_struct
1693            });
1694            tuple.insert({
1695                let mut map = DynamicMap::default();
1696                map.insert(1usize, {
1697                    let mut struct_ = DynamicStruct::default();
1698                    struct_.insert("x", 7u32);
1699                    struct_
1700                });
1701                map
1702            });
1703            tuple
1704        });
1705        foo_patch.insert("g", composite);
1706
1707        let array = DynamicArray::from_iter([2u32, 2u32]);
1708        foo_patch.insert("h", array);
1709
1710        foo.apply(&foo_patch);
1711
1712        let mut hash_map = <HashMap<_, _>>::default();
1713        hash_map.insert(2, 3);
1714        hash_map.insert(3, 4);
1715
1716        let mut hash_map_baz = <HashMap<_, _>>::default();
1717        hash_map_baz.insert(1, Bar { x: 7 });
1718
1719        let expected_foo = Foo {
1720            a: 2,
1721            _b: 1,
1722            c: vec![3, 4, 5],
1723            d: hash_map,
1724            e: Bar { x: 2 },
1725            f: (2, vec![3, 4, 5], Bar { x: 2 }),
1726            g: vec![(Baz("new_string".to_string()), hash_map_baz.clone())],
1727            h: [2; 2],
1728        };
1729
1730        assert_eq!(foo, expected_foo);
1731
1732        let new_foo = Foo::from_reflect(&foo_patch)
1733            .expect("error while creating a concrete type from a dynamic type");
1734
1735        let mut hash_map = <HashMap<_, _>>::default();
1736        hash_map.insert(2, 3);
1737        hash_map.insert(3, 4);
1738
1739        let expected_new_foo = Foo {
1740            a: 2,
1741            _b: 0,
1742            c: vec![3, 4, 5],
1743            d: hash_map,
1744            e: Bar { x: 2 },
1745            f: (2, vec![3, 4, 5], Bar { x: 2 }),
1746            g: vec![(Baz("new_string".to_string()), hash_map_baz)],
1747            h: [2; 2],
1748        };
1749
1750        assert_eq!(new_foo, expected_new_foo);
1751    }
1752
1753    #[test]
1754    fn should_auto_register_fields() {
1755        #[derive(Reflect)]
1756        struct Foo {
1757            bar: Bar,
1758        }
1759
1760        #[derive(Reflect)]
1761        enum Bar {
1762            Variant(Baz),
1763        }
1764
1765        #[derive(Reflect)]
1766        struct Baz(usize);
1767
1768        // === Basic === //
1769        let mut registry = TypeRegistry::empty();
1770        registry.register::<Foo>();
1771
1772        assert!(
1773            registry.contains(TypeId::of::<Bar>()),
1774            "registry should contain auto-registered `Bar` from `Foo`"
1775        );
1776
1777        // === Option === //
1778        let mut registry = TypeRegistry::empty();
1779        registry.register::<Option<Foo>>();
1780
1781        assert!(
1782            registry.contains(TypeId::of::<Bar>()),
1783            "registry should contain auto-registered `Bar` from `Option<Foo>`"
1784        );
1785
1786        // === Tuple === //
1787        let mut registry = TypeRegistry::empty();
1788        registry.register::<(Foo, Foo)>();
1789
1790        assert!(
1791            registry.contains(TypeId::of::<Bar>()),
1792            "registry should contain auto-registered `Bar` from `(Foo, Foo)`"
1793        );
1794
1795        // === Array === //
1796        let mut registry = TypeRegistry::empty();
1797        registry.register::<[Foo; 3]>();
1798
1799        assert!(
1800            registry.contains(TypeId::of::<Bar>()),
1801            "registry should contain auto-registered `Bar` from `[Foo; 3]`"
1802        );
1803
1804        // === Vec === //
1805        let mut registry = TypeRegistry::empty();
1806        registry.register::<Vec<Foo>>();
1807
1808        assert!(
1809            registry.contains(TypeId::of::<Bar>()),
1810            "registry should contain auto-registered `Bar` from `Vec<Foo>`"
1811        );
1812
1813        // === HashMap === //
1814        let mut registry = TypeRegistry::empty();
1815        registry.register::<HashMap<i32, Foo>>();
1816
1817        assert!(
1818            registry.contains(TypeId::of::<Bar>()),
1819            "registry should contain auto-registered `Bar` from `HashMap<i32, Foo>`"
1820        );
1821    }
1822
1823    #[test]
1824    fn should_allow_dynamic_fields() {
1825        #[derive(Reflect)]
1826        #[reflect(from_reflect = false)]
1827        struct MyStruct(
1828            DynamicEnum,
1829            DynamicTupleStruct,
1830            DynamicStruct,
1831            DynamicMap,
1832            DynamicList,
1833            DynamicArray,
1834            DynamicTuple,
1835            i32,
1836        );
1837
1838        assert_impl_all!(MyStruct: Reflect, GetTypeRegistration);
1839
1840        let mut registry = TypeRegistry::empty();
1841        registry.register::<MyStruct>();
1842
1843        assert_eq!(2, registry.iter().count());
1844        assert!(registry.contains(TypeId::of::<MyStruct>()));
1845        assert!(registry.contains(TypeId::of::<i32>()));
1846    }
1847
1848    #[test]
1849    fn should_not_auto_register_existing_types() {
1850        #[derive(Reflect)]
1851        struct Foo {
1852            bar: Bar,
1853        }
1854
1855        #[derive(Reflect, Default)]
1856        struct Bar(usize);
1857
1858        let mut registry = TypeRegistry::empty();
1859        registry.register::<Bar>();
1860        registry.register_type_data::<Bar, ReflectDefault>();
1861        registry.register::<Foo>();
1862
1863        assert!(
1864            registry
1865                .get_type_data::<ReflectDefault>(TypeId::of::<Bar>())
1866                .is_some(),
1867            "registry should contain existing registration for `Bar`"
1868        );
1869    }
1870
1871    #[test]
1872    fn reflect_serialize() {
1873        #[derive(Reflect)]
1874        struct Foo {
1875            a: u32,
1876            #[reflect(ignore)]
1877            _b: u32,
1878            c: Vec<isize>,
1879            d: HashMap<usize, i8>,
1880            e: Bar,
1881            f: String,
1882            g: (i32, Vec<isize>, Bar),
1883            h: [u32; 2],
1884        }
1885
1886        #[derive(Reflect, Serialize, Deserialize)]
1887        #[reflect(Serialize, Deserialize)]
1888        struct Bar {
1889            x: u32,
1890        }
1891
1892        let mut hash_map = <HashMap<_, _>>::default();
1893        hash_map.insert(1, 1);
1894        hash_map.insert(2, 2);
1895        let foo = Foo {
1896            a: 1,
1897            _b: 1,
1898            c: vec![1, 2],
1899            d: hash_map,
1900            e: Bar { x: 1 },
1901            f: "hi".to_string(),
1902            g: (1, vec![1, 2], Bar { x: 1 }),
1903            h: [2; 2],
1904        };
1905
1906        let mut registry = TypeRegistry::default();
1907        registry.register::<u32>();
1908        registry.register::<i8>();
1909        registry.register::<i32>();
1910        registry.register::<usize>();
1911        registry.register::<isize>();
1912        registry.register::<Foo>();
1913        registry.register::<Bar>();
1914        registry.register::<String>();
1915        registry.register::<Vec<isize>>();
1916        registry.register::<HashMap<usize, i8>>();
1917        registry.register::<(i32, Vec<isize>, Bar)>();
1918        registry.register::<[u32; 2]>();
1919
1920        let serializer = ReflectSerializer::new(&foo, &registry);
1921        let serialized = to_string_pretty(&serializer, PrettyConfig::default()).unwrap();
1922
1923        let mut deserializer = Deserializer::from_str(&serialized).unwrap();
1924        let reflect_deserializer = ReflectDeserializer::new(&registry);
1925        let value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
1926        let roundtrip_foo = Foo::from_reflect(value.as_partial_reflect()).unwrap();
1927
1928        assert!(foo.reflect_partial_eq(&roundtrip_foo).unwrap());
1929    }
1930
1931    #[test]
1932    fn reflect_downcast() {
1933        #[derive(Reflect, Clone, Debug, PartialEq)]
1934        struct Bar {
1935            y: u8,
1936        }
1937
1938        #[derive(Reflect, Clone, Debug, PartialEq)]
1939        struct Foo {
1940            x: i32,
1941            s: String,
1942            b: Bar,
1943            u: usize,
1944            t: ([f32; 3], String),
1945            v: Cow<'static, str>,
1946            w: Cow<'static, [u8]>,
1947        }
1948
1949        let foo = Foo {
1950            x: 123,
1951            s: "String".to_string(),
1952            b: Bar { y: 255 },
1953            u: 1111111111111,
1954            t: ([3.0, 2.0, 1.0], "Tuple String".to_string()),
1955            v: Cow::Owned("Cow String".to_string()),
1956            w: Cow::Owned(vec![1, 2, 3]),
1957        };
1958
1959        let foo2: Box<dyn Reflect> = Box::new(foo.clone());
1960
1961        assert_eq!(foo, *foo2.downcast::<Foo>().unwrap());
1962    }
1963
1964    #[test]
1965    fn should_drain_fields() {
1966        let array_value: Box<dyn Array> = Box::new([123_i32, 321_i32]);
1967        let fields = array_value.drain();
1968        assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1969        assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1970
1971        let mut list_value: Box<dyn List> = Box::new(vec![123_i32, 321_i32]);
1972        let fields = list_value.drain();
1973        assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1974        assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1975
1976        let tuple_value: Box<dyn Tuple> = Box::new((123_i32, 321_i32));
1977        let fields = tuple_value.drain();
1978        assert!(fields[0].reflect_partial_eq(&123_i32).unwrap_or_default());
1979        assert!(fields[1].reflect_partial_eq(&321_i32).unwrap_or_default());
1980
1981        let mut map_value: Box<dyn Map> =
1982            Box::new([(123_i32, 321_i32)].into_iter().collect::<HashMap<_, _>>());
1983        let fields = map_value.drain();
1984        assert!(fields[0].0.reflect_partial_eq(&123_i32).unwrap_or_default());
1985        assert!(fields[0].1.reflect_partial_eq(&321_i32).unwrap_or_default());
1986    }
1987
1988    #[test]
1989    fn reflect_take() {
1990        #[derive(Reflect, Debug, PartialEq)]
1991        #[reflect(PartialEq)]
1992        struct Bar {
1993            x: u32,
1994        }
1995
1996        let x: Box<dyn Reflect> = Box::new(Bar { x: 2 });
1997        let y = x.take::<Bar>().unwrap();
1998        assert_eq!(y, Bar { x: 2 });
1999    }
2000
2001    #[test]
2002    fn not_dynamic_names() {
2003        let list = Vec::<usize>::new();
2004        let dyn_list = list.to_dynamic_list();
2005        assert_ne!(dyn_list.reflect_type_path(), Vec::<usize>::type_path());
2006
2007        let array = [b'0'; 4];
2008        let dyn_array = array.to_dynamic_array();
2009        assert_ne!(dyn_array.reflect_type_path(), <[u8; 4]>::type_path());
2010
2011        let map = HashMap::<usize, String>::default();
2012        let dyn_map = map.to_dynamic_map();
2013        assert_ne!(
2014            dyn_map.reflect_type_path(),
2015            HashMap::<usize, String>::type_path()
2016        );
2017
2018        let tuple = (0usize, "1".to_string(), 2.0f32);
2019        let mut dyn_tuple = tuple.to_dynamic_tuple();
2020        dyn_tuple.insert::<usize>(3);
2021        assert_ne!(
2022            dyn_tuple.reflect_type_path(),
2023            <(usize, String, f32, usize)>::type_path()
2024        );
2025
2026        #[derive(Reflect)]
2027        struct TestStruct {
2028            a: usize,
2029        }
2030        let struct_ = TestStruct { a: 0 };
2031        let dyn_struct = struct_.to_dynamic_struct();
2032        assert_ne!(dyn_struct.reflect_type_path(), TestStruct::type_path());
2033
2034        #[derive(Reflect)]
2035        struct TestTupleStruct(usize);
2036        let tuple_struct = TestTupleStruct(0);
2037        let dyn_tuple_struct = tuple_struct.to_dynamic_tuple_struct();
2038        assert_ne!(
2039            dyn_tuple_struct.reflect_type_path(),
2040            TestTupleStruct::type_path()
2041        );
2042    }
2043
2044    macro_rules! assert_type_paths {
2045        ($($ty:ty => $long:literal, $short:literal,)*) => {
2046            $(
2047                assert_eq!(<$ty as TypePath>::type_path(), $long);
2048                assert_eq!(<$ty as TypePath>::short_type_path(), $short);
2049            )*
2050        };
2051    }
2052
2053    #[test]
2054    fn reflect_type_path() {
2055        #[derive(TypePath)]
2056        struct Param;
2057
2058        #[derive(TypePath)]
2059        struct Derive;
2060
2061        #[derive(TypePath)]
2062        #[type_path = "my_alias"]
2063        struct DerivePath;
2064
2065        #[derive(TypePath)]
2066        #[type_path = "my_alias"]
2067        #[type_name = "MyDerivePathName"]
2068        struct DerivePathName;
2069
2070        #[derive(TypePath)]
2071        struct DeriveG<T>(PhantomData<T>);
2072
2073        #[derive(TypePath)]
2074        #[type_path = "my_alias"]
2075        struct DerivePathG<T, const N: usize>(PhantomData<T>);
2076
2077        #[derive(TypePath)]
2078        #[type_path = "my_alias"]
2079        #[type_name = "MyDerivePathNameG"]
2080        struct DerivePathNameG<T>(PhantomData<T>);
2081
2082        struct Macro;
2083        impl_type_path!((in my_alias) Macro);
2084
2085        struct MacroName;
2086        impl_type_path!((in my_alias as MyMacroName) MacroName);
2087
2088        struct MacroG<T, const N: usize>(PhantomData<T>);
2089        impl_type_path!((in my_alias) MacroG<T, const N: usize>);
2090
2091        struct MacroNameG<T>(PhantomData<T>);
2092        impl_type_path!((in my_alias as MyMacroNameG) MacroNameG<T>);
2093
2094        assert_type_paths! {
2095            Derive => "bevy_reflect::tests::Derive", "Derive",
2096            DerivePath => "my_alias::DerivePath", "DerivePath",
2097            DerivePathName => "my_alias::MyDerivePathName", "MyDerivePathName",
2098            DeriveG<Param> => "bevy_reflect::tests::DeriveG<bevy_reflect::tests::Param>", "DeriveG<Param>",
2099            DerivePathG<Param, 10> => "my_alias::DerivePathG<bevy_reflect::tests::Param, 10>", "DerivePathG<Param, 10>",
2100            DerivePathNameG<Param> => "my_alias::MyDerivePathNameG<bevy_reflect::tests::Param>", "MyDerivePathNameG<Param>",
2101            Macro => "my_alias::Macro", "Macro",
2102            MacroName => "my_alias::MyMacroName", "MyMacroName",
2103            MacroG<Param, 10> => "my_alias::MacroG<bevy_reflect::tests::Param, 10>", "MacroG<Param, 10>",
2104            MacroNameG<Param> => "my_alias::MyMacroNameG<bevy_reflect::tests::Param>", "MyMacroNameG<Param>",
2105        }
2106    }
2107
2108    #[test]
2109    fn std_type_paths() {
2110        #[derive(Clone)]
2111        struct Type;
2112
2113        impl TypePath for Type {
2114            fn type_path() -> &'static str {
2115                // for brevity in tests
2116                "Long"
2117            }
2118
2119            fn short_type_path() -> &'static str {
2120                "Short"
2121            }
2122        }
2123
2124        assert_type_paths! {
2125            u8 => "u8", "u8",
2126            Type => "Long", "Short",
2127            &Type => "&Long", "&Short",
2128            [Type] => "[Long]", "[Short]",
2129            &[Type] => "&[Long]", "&[Short]",
2130            [Type; 0] => "[Long; 0]", "[Short; 0]",
2131            [Type; 100] => "[Long; 100]", "[Short; 100]",
2132            () => "()", "()",
2133            (Type,) => "(Long,)", "(Short,)",
2134            (Type, Type) => "(Long, Long)", "(Short, Short)",
2135            (Type, Type, Type) => "(Long, Long, Long)", "(Short, Short, Short)",
2136            Cow<'static, Type> => "alloc::borrow::Cow<Long>", "Cow<Short>",
2137        }
2138    }
2139
2140    #[test]
2141    fn reflect_type_info() {
2142        // TypeInfo
2143        let info = i32::type_info();
2144        assert_eq!(i32::type_path(), info.type_path());
2145        assert_eq!(TypeId::of::<i32>(), info.type_id());
2146
2147        // TypeInfo (unsized)
2148        assert_eq!(
2149            TypeId::of::<dyn Reflect>(),
2150            <dyn Reflect as Typed>::type_info().type_id()
2151        );
2152
2153        // TypeInfo (instance)
2154        let value: &dyn Reflect = &123_i32;
2155        let info = value.reflect_type_info();
2156        assert!(info.is::<i32>());
2157
2158        // Struct
2159        #[derive(Reflect)]
2160        struct MyStruct {
2161            foo: i32,
2162            bar: usize,
2163        }
2164
2165        let info = MyStruct::type_info().as_struct().unwrap();
2166        assert!(info.is::<MyStruct>());
2167        assert_eq!(MyStruct::type_path(), info.type_path());
2168        assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
2169        assert_eq!(TypeId::of::<i32>(), info.field("foo").unwrap().type_id());
2170        assert!(info.field("foo").unwrap().type_info().unwrap().is::<i32>());
2171        assert!(info.field("foo").unwrap().is::<i32>());
2172        assert_eq!("foo", info.field("foo").unwrap().name());
2173        assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2174
2175        let value: &dyn Reflect = &MyStruct { foo: 123, bar: 321 };
2176        let info = value.reflect_type_info();
2177        assert!(info.is::<MyStruct>());
2178
2179        // Struct (generic)
2180        #[derive(Reflect)]
2181        struct MyGenericStruct<T> {
2182            foo: T,
2183            bar: usize,
2184        }
2185
2186        let info = <MyGenericStruct<i32>>::type_info().as_struct().unwrap();
2187        assert!(info.is::<MyGenericStruct<i32>>());
2188        assert_eq!(MyGenericStruct::<i32>::type_path(), info.type_path());
2189        assert_eq!(i32::type_path(), info.field("foo").unwrap().type_path());
2190        assert_eq!("foo", info.field("foo").unwrap().name());
2191        assert!(info.field("foo").unwrap().type_info().unwrap().is::<i32>());
2192        assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2193
2194        let value: &dyn Reflect = &MyGenericStruct {
2195            foo: String::from("Hello!"),
2196            bar: 321,
2197        };
2198        let info = value.reflect_type_info();
2199        assert!(info.is::<MyGenericStruct<String>>());
2200
2201        // Struct (dynamic field)
2202        #[derive(Reflect)]
2203        #[reflect(from_reflect = false)]
2204        struct MyDynamicStruct {
2205            foo: DynamicStruct,
2206            bar: usize,
2207        }
2208
2209        let info = MyDynamicStruct::type_info();
2210        if let TypeInfo::Struct(info) = info {
2211            assert!(info.is::<MyDynamicStruct>());
2212            assert_eq!(MyDynamicStruct::type_path(), info.type_path());
2213            assert_eq!(
2214                DynamicStruct::type_path(),
2215                info.field("foo").unwrap().type_path()
2216            );
2217            assert_eq!("foo", info.field("foo").unwrap().name());
2218            assert!(info.field("foo").unwrap().type_info().is_none());
2219            assert_eq!(usize::type_path(), info.field_at(1).unwrap().type_path());
2220        } else {
2221            panic!("Expected `TypeInfo::Struct`");
2222        }
2223
2224        let value: &dyn Reflect = &MyDynamicStruct {
2225            foo: DynamicStruct::default(),
2226            bar: 321,
2227        };
2228        let info = value.reflect_type_info();
2229        assert!(info.is::<MyDynamicStruct>());
2230
2231        // Tuple Struct
2232        #[derive(Reflect)]
2233        struct MyTupleStruct(usize, i32, MyStruct);
2234
2235        let info = MyTupleStruct::type_info().as_tuple_struct().unwrap();
2236
2237        assert!(info.is::<MyTupleStruct>());
2238        assert_eq!(MyTupleStruct::type_path(), info.type_path());
2239        assert_eq!(i32::type_path(), info.field_at(1).unwrap().type_path());
2240        assert!(info.field_at(1).unwrap().type_info().unwrap().is::<i32>());
2241        assert!(info.field_at(1).unwrap().is::<i32>());
2242
2243        // Tuple
2244        type MyTuple = (u32, f32, String);
2245
2246        let info = MyTuple::type_info().as_tuple().unwrap();
2247
2248        assert!(info.is::<MyTuple>());
2249        assert_eq!(MyTuple::type_path(), info.type_path());
2250        assert_eq!(f32::type_path(), info.field_at(1).unwrap().type_path());
2251        assert!(info.field_at(1).unwrap().type_info().unwrap().is::<f32>());
2252
2253        let value: &dyn Reflect = &(123_u32, 1.23_f32, String::from("Hello!"));
2254        let info = value.reflect_type_info();
2255        assert!(info.is::<MyTuple>());
2256
2257        // List
2258        type MyList = Vec<usize>;
2259
2260        let info = MyList::type_info().as_list().unwrap();
2261
2262        assert!(info.is::<MyList>());
2263        assert!(info.item_ty().is::<usize>());
2264        assert!(info.item_info().unwrap().is::<usize>());
2265        assert_eq!(MyList::type_path(), info.type_path());
2266        assert_eq!(usize::type_path(), info.item_ty().path());
2267
2268        let value: &dyn Reflect = &vec![123_usize];
2269        let info = value.reflect_type_info();
2270        assert!(info.is::<MyList>());
2271
2272        // List (SmallVec)
2273        #[cfg(feature = "smallvec")]
2274        {
2275            type MySmallVec = smallvec::SmallVec<[String; 2]>;
2276
2277            let info = MySmallVec::type_info().as_list().unwrap();
2278            assert!(info.is::<MySmallVec>());
2279            assert!(info.item_ty().is::<String>());
2280            assert!(info.item_info().unwrap().is::<String>());
2281            assert_eq!(MySmallVec::type_path(), info.type_path());
2282            assert_eq!(String::type_path(), info.item_ty().path());
2283
2284            let value: MySmallVec = smallvec::smallvec![String::default(); 2];
2285            let value: &dyn Reflect = &value;
2286            let info = value.reflect_type_info();
2287            assert!(info.is::<MySmallVec>());
2288        }
2289
2290        // Array
2291        type MyArray = [usize; 3];
2292
2293        let info = MyArray::type_info().as_array().unwrap();
2294        assert!(info.is::<MyArray>());
2295        assert!(info.item_ty().is::<usize>());
2296        assert!(info.item_info().unwrap().is::<usize>());
2297        assert_eq!(MyArray::type_path(), info.type_path());
2298        assert_eq!(usize::type_path(), info.item_ty().path());
2299        assert_eq!(3, info.capacity());
2300
2301        let value: &dyn Reflect = &[1usize, 2usize, 3usize];
2302        let info = value.reflect_type_info();
2303        assert!(info.is::<MyArray>());
2304
2305        // Cow<'static, str>
2306        type MyCowStr = Cow<'static, str>;
2307
2308        let info = MyCowStr::type_info().as_opaque().unwrap();
2309
2310        assert!(info.is::<MyCowStr>());
2311        assert_eq!("alloc::borrow::Cow<str>", info.type_path());
2312
2313        let value: &dyn Reflect = &Cow::<'static, str>::Owned("Hello!".to_string());
2314        let info = value.reflect_type_info();
2315        assert!(info.is::<MyCowStr>());
2316
2317        // Cow<'static, [u8]>
2318        type MyCowSlice = Cow<'static, [u8]>;
2319
2320        let info = MyCowSlice::type_info().as_list().unwrap();
2321
2322        assert!(info.is::<MyCowSlice>());
2323        assert!(info.item_ty().is::<u8>());
2324        assert!(info.item_info().unwrap().is::<u8>());
2325        assert_eq!("alloc::borrow::Cow<[u8]>", info.type_path());
2326        assert_eq!("u8", info.item_ty().path());
2327
2328        let value: &dyn Reflect = &Cow::<'static, [u8]>::Owned(vec![0, 1, 2, 3]);
2329        let info = value.reflect_type_info();
2330        assert!(info.is::<MyCowSlice>());
2331
2332        // Map
2333        type MyMap = HashMap<usize, f32>;
2334
2335        let info = MyMap::type_info().as_map().unwrap();
2336
2337        assert!(info.is::<MyMap>());
2338        assert!(info.key_ty().is::<usize>());
2339        assert!(info.value_ty().is::<f32>());
2340        assert!(info.key_info().unwrap().is::<usize>());
2341        assert!(info.value_info().unwrap().is::<f32>());
2342        assert_eq!(MyMap::type_path(), info.type_path());
2343        assert_eq!(usize::type_path(), info.key_ty().path());
2344        assert_eq!(f32::type_path(), info.value_ty().path());
2345
2346        let value: &dyn Reflect = &MyMap::default();
2347        let info = value.reflect_type_info();
2348        assert!(info.is::<MyMap>());
2349
2350        // Map (IndexMap)
2351        #[cfg(feature = "indexmap")]
2352        {
2353            use std::hash::RandomState;
2354
2355            type MyIndexMap = indexmap::IndexMap<String, u32, RandomState>;
2356
2357            let info = MyIndexMap::type_info().as_map().unwrap();
2358            assert!(info.is::<MyIndexMap>());
2359            assert_eq!(MyIndexMap::type_path(), info.type_path());
2360
2361            assert!(info.key_ty().is::<String>());
2362            assert!(info.key_info().unwrap().is::<String>());
2363            assert_eq!(String::type_path(), info.key_ty().path());
2364
2365            assert!(info.value_ty().is::<u32>());
2366            assert!(info.value_info().unwrap().is::<u32>());
2367            assert_eq!(u32::type_path(), info.value_ty().path());
2368
2369            let value: MyIndexMap = MyIndexMap::with_capacity_and_hasher(10, RandomState::new());
2370            let value: &dyn Reflect = &value;
2371            let info = value.reflect_type_info();
2372            assert!(info.is::<MyIndexMap>());
2373        }
2374
2375        // Value
2376        type MyValue = String;
2377
2378        let info = MyValue::type_info().as_opaque().unwrap();
2379
2380        assert!(info.is::<MyValue>());
2381        assert_eq!(MyValue::type_path(), info.type_path());
2382
2383        let value: &dyn Reflect = &String::from("Hello!");
2384        let info = value.reflect_type_info();
2385        assert!(info.is::<MyValue>());
2386    }
2387
2388    #[test]
2389    fn get_represented_kind_info() {
2390        #[derive(Reflect)]
2391        struct SomeStruct;
2392
2393        #[derive(Reflect)]
2394        struct SomeTupleStruct(f32);
2395
2396        #[derive(Reflect)]
2397        enum SomeEnum {
2398            Foo,
2399            Bar,
2400        }
2401
2402        let dyn_struct: &dyn Struct = &SomeStruct;
2403        let _: &StructInfo = dyn_struct.get_represented_struct_info().unwrap();
2404
2405        let dyn_map: &dyn Map = &HashMap::<(), ()>::default();
2406        let _: &MapInfo = dyn_map.get_represented_map_info().unwrap();
2407
2408        let dyn_array: &dyn Array = &[1, 2, 3];
2409        let _: &ArrayInfo = dyn_array.get_represented_array_info().unwrap();
2410
2411        let dyn_list: &dyn List = &vec![1, 2, 3];
2412        let _: &ListInfo = dyn_list.get_represented_list_info().unwrap();
2413
2414        let dyn_tuple_struct: &dyn TupleStruct = &SomeTupleStruct(5.0);
2415        let _: &TupleStructInfo = dyn_tuple_struct
2416            .get_represented_tuple_struct_info()
2417            .unwrap();
2418
2419        let dyn_enum: &dyn Enum = &SomeEnum::Foo;
2420        let _: &EnumInfo = dyn_enum.get_represented_enum_info().unwrap();
2421    }
2422
2423    #[test]
2424    fn should_permit_higher_ranked_lifetimes() {
2425        #[derive(Reflect)]
2426        #[reflect(from_reflect = false)]
2427        struct TestStruct {
2428            #[reflect(ignore)]
2429            _hrl: for<'a> fn(&'a str) -> &'a str,
2430        }
2431
2432        impl Default for TestStruct {
2433            fn default() -> Self {
2434                TestStruct {
2435                    _hrl: |input| input,
2436                }
2437            }
2438        }
2439
2440        fn get_type_registration<T: GetTypeRegistration>() {}
2441        get_type_registration::<TestStruct>();
2442    }
2443
2444    #[test]
2445    fn should_permit_valid_represented_type_for_dynamic() {
2446        let type_info = <[i32; 2] as Typed>::type_info();
2447        let mut dynamic_array = [123; 2].to_dynamic_array();
2448        dynamic_array.set_represented_type(Some(type_info));
2449    }
2450
2451    #[test]
2452    #[should_panic(expected = "expected TypeInfo::Array but received")]
2453    fn should_prohibit_invalid_represented_type_for_dynamic() {
2454        let type_info = <(i32, i32) as Typed>::type_info();
2455        let mut dynamic_array = [123; 2].to_dynamic_array();
2456        dynamic_array.set_represented_type(Some(type_info));
2457    }
2458
2459    #[cfg(feature = "reflect_documentation")]
2460    mod docstrings {
2461        use super::*;
2462
2463        #[test]
2464        fn should_not_contain_docs() {
2465            // Regular comments do not count as doc comments,
2466            // and are therefore not reflected.
2467            #[derive(Reflect)]
2468            struct SomeStruct;
2469
2470            let info = <SomeStruct as Typed>::type_info();
2471            assert_eq!(None, info.docs());
2472
2473            // Block comments do not count as doc comments,
2474            // and are therefore not reflected.
2475            #[derive(Reflect)]
2476            struct SomeOtherStruct;
2477
2478            let info = <SomeOtherStruct as Typed>::type_info();
2479            assert_eq!(None, info.docs());
2480        }
2481
2482        #[test]
2483        fn should_contain_docs() {
2484            /// Some struct.
2485            ///
2486            /// # Example
2487            ///
2488            /// ```ignore (This is only used for a unit test, no need to doc test)
2489            /// let some_struct = SomeStruct;
2490            /// ```
2491            #[derive(Reflect)]
2492            struct SomeStruct;
2493
2494            let info = <SomeStruct as Typed>::type_info();
2495            assert_eq!(
2496                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 ```"),
2497                info.docs()
2498            );
2499
2500            #[doc = "The compiler automatically converts `///`-style comments into `#[doc]` attributes."]
2501            #[doc = "Of course, you _could_ use the attribute directly if you wanted to."]
2502            #[doc = "Both will be reflected."]
2503            #[derive(Reflect)]
2504            struct SomeOtherStruct;
2505
2506            let info = <SomeOtherStruct as Typed>::type_info();
2507            assert_eq!(
2508                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."),
2509                info.docs()
2510            );
2511
2512            /// Some tuple struct.
2513            #[derive(Reflect)]
2514            struct SomeTupleStruct(usize);
2515
2516            let info = <SomeTupleStruct as Typed>::type_info();
2517            assert_eq!(Some(" Some tuple struct."), info.docs());
2518
2519            /// Some enum.
2520            #[derive(Reflect)]
2521            enum SomeEnum {
2522                Foo,
2523            }
2524
2525            let info = <SomeEnum as Typed>::type_info();
2526            assert_eq!(Some(" Some enum."), info.docs());
2527
2528            #[derive(Clone)]
2529            struct SomePrimitive;
2530            impl_reflect_opaque!(
2531                /// Some primitive for which we have attributed custom documentation.
2532                (in bevy_reflect::tests) SomePrimitive
2533            );
2534
2535            let info = <SomePrimitive as Typed>::type_info();
2536            assert_eq!(
2537                Some(" Some primitive for which we have attributed custom documentation."),
2538                info.docs()
2539            );
2540        }
2541
2542        #[test]
2543        fn fields_should_contain_docs() {
2544            #[derive(Reflect)]
2545            struct SomeStruct {
2546                /// The name
2547                name: String,
2548                /// The index
2549                index: usize,
2550                // Not documented...
2551                data: Vec<i32>,
2552            }
2553
2554            let info = <SomeStruct as Typed>::type_info().as_struct().unwrap();
2555
2556            let mut fields = info.iter();
2557            assert_eq!(Some(" The name"), fields.next().unwrap().docs());
2558            assert_eq!(Some(" The index"), fields.next().unwrap().docs());
2559            assert_eq!(None, fields.next().unwrap().docs());
2560        }
2561
2562        #[test]
2563        fn variants_should_contain_docs() {
2564            #[derive(Reflect)]
2565            enum SomeEnum {
2566                // Not documented...
2567                Nothing,
2568                /// Option A
2569                A(
2570                    /// Index
2571                    usize,
2572                ),
2573                /// Option B
2574                B {
2575                    /// Name
2576                    name: String,
2577                },
2578            }
2579
2580            let info = <SomeEnum as Typed>::type_info().as_enum().unwrap();
2581
2582            let mut variants = info.iter();
2583            assert_eq!(None, variants.next().unwrap().docs());
2584
2585            let variant = variants.next().unwrap().as_tuple_variant().unwrap();
2586            assert_eq!(Some(" Option A"), variant.docs());
2587            let field = variant.field_at(0).unwrap();
2588            assert_eq!(Some(" Index"), field.docs());
2589
2590            let variant = variants.next().unwrap().as_struct_variant().unwrap();
2591            assert_eq!(Some(" Option B"), variant.docs());
2592            let field = variant.field_at(0).unwrap();
2593            assert_eq!(Some(" Name"), field.docs());
2594        }
2595    }
2596
2597    #[test]
2598    fn into_reflect() {
2599        trait TestTrait: Reflect {}
2600
2601        #[derive(Reflect)]
2602        struct TestStruct;
2603
2604        impl TestTrait for TestStruct {}
2605
2606        let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
2607
2608        // Should compile:
2609        let _ = trait_object.into_reflect();
2610    }
2611
2612    #[test]
2613    fn as_reflect() {
2614        trait TestTrait: Reflect {}
2615
2616        #[derive(Reflect)]
2617        struct TestStruct;
2618
2619        impl TestTrait for TestStruct {}
2620
2621        let trait_object: Box<dyn TestTrait> = Box::new(TestStruct);
2622
2623        // Should compile:
2624        let _ = trait_object.as_reflect();
2625    }
2626
2627    #[test]
2628    fn should_reflect_debug() {
2629        #[derive(Reflect)]
2630        struct Test {
2631            value: usize,
2632            list: Vec<String>,
2633            array: [f32; 3],
2634            map: HashMap<i32, f32>,
2635            a_struct: SomeStruct,
2636            a_tuple_struct: SomeTupleStruct,
2637            enum_unit: SomeEnum,
2638            enum_tuple: SomeEnum,
2639            enum_struct: SomeEnum,
2640            custom: CustomDebug,
2641            #[reflect(ignore)]
2642            #[expect(dead_code, reason = "This value is intended to not be reflected.")]
2643            ignored: isize,
2644        }
2645
2646        #[derive(Reflect)]
2647        struct SomeStruct {
2648            foo: String,
2649        }
2650
2651        #[derive(Reflect)]
2652        enum SomeEnum {
2653            A,
2654            B(usize),
2655            C { value: i32 },
2656        }
2657
2658        #[derive(Reflect)]
2659        struct SomeTupleStruct(String);
2660
2661        #[derive(Reflect)]
2662        #[reflect(Debug)]
2663        struct CustomDebug;
2664        impl Debug for CustomDebug {
2665            fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
2666                f.write_str("Cool debug!")
2667            }
2668        }
2669
2670        let mut map = <HashMap<_, _>>::default();
2671        map.insert(123, 1.23);
2672
2673        let test = Test {
2674            value: 123,
2675            list: vec![String::from("A"), String::from("B"), String::from("C")],
2676            array: [1.0, 2.0, 3.0],
2677            map,
2678            a_struct: SomeStruct {
2679                foo: String::from("A Struct!"),
2680            },
2681            a_tuple_struct: SomeTupleStruct(String::from("A Tuple Struct!")),
2682            enum_unit: SomeEnum::A,
2683            enum_tuple: SomeEnum::B(123),
2684            enum_struct: SomeEnum::C { value: 321 },
2685            custom: CustomDebug,
2686            ignored: 321,
2687        };
2688
2689        let reflected: &dyn Reflect = &test;
2690        let expected = r#"
2691bevy_reflect::tests::Test {
2692    value: 123,
2693    list: [
2694        "A",
2695        "B",
2696        "C",
2697    ],
2698    array: [
2699        1.0,
2700        2.0,
2701        3.0,
2702    ],
2703    map: {
2704        123: 1.23,
2705    },
2706    a_struct: bevy_reflect::tests::SomeStruct {
2707        foo: "A Struct!",
2708    },
2709    a_tuple_struct: bevy_reflect::tests::SomeTupleStruct(
2710        "A Tuple Struct!",
2711    ),
2712    enum_unit: A,
2713    enum_tuple: B(
2714        123,
2715    ),
2716    enum_struct: C {
2717        value: 321,
2718    },
2719    custom: Cool debug!,
2720}"#;
2721
2722        assert_eq!(expected, format!("\n{reflected:#?}"));
2723    }
2724
2725    #[test]
2726    fn multiple_reflect_lists() {
2727        #[derive(Hash, PartialEq, Reflect)]
2728        #[reflect(Debug, Hash)]
2729        #[reflect(PartialEq)]
2730        struct Foo(i32);
2731
2732        impl Debug for Foo {
2733            fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
2734                write!(f, "Foo")
2735            }
2736        }
2737
2738        let foo = Foo(123);
2739        let foo: &dyn PartialReflect = &foo;
2740
2741        assert!(foo.reflect_hash().is_some());
2742        assert_eq!(Some(true), foo.reflect_partial_eq(foo));
2743        assert_eq!("Foo".to_string(), format!("{foo:?}"));
2744    }
2745
2746    #[test]
2747    fn custom_debug_function() {
2748        #[derive(Reflect)]
2749        #[reflect(Debug(custom_debug))]
2750        struct Foo {
2751            a: u32,
2752        }
2753
2754        fn custom_debug(_x: &Foo, f: &mut Formatter<'_>) -> core::fmt::Result {
2755            write!(f, "123")
2756        }
2757
2758        let foo = Foo { a: 1 };
2759        let foo: &dyn Reflect = &foo;
2760
2761        assert_eq!("123", format!("{foo:?}"));
2762    }
2763
2764    #[test]
2765    fn should_allow_custom_where() {
2766        #[derive(Reflect)]
2767        #[reflect(where T: Default)]
2768        struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
2769
2770        #[derive(Default, TypePath)]
2771        struct Bar;
2772
2773        #[derive(TypePath)]
2774        struct Baz;
2775
2776        assert_impl_all!(Foo<Bar>: Reflect);
2777        assert_not_impl_all!(Foo<Baz>: Reflect);
2778    }
2779
2780    #[test]
2781    fn should_allow_empty_custom_where() {
2782        #[derive(Reflect)]
2783        #[reflect(where)]
2784        struct Foo<T>(String, #[reflect(ignore)] PhantomData<T>);
2785
2786        #[derive(TypePath)]
2787        struct Bar;
2788
2789        assert_impl_all!(Foo<Bar>: Reflect);
2790    }
2791
2792    #[test]
2793    fn should_allow_multiple_custom_where() {
2794        #[derive(Reflect)]
2795        #[reflect(where T: Default)]
2796        #[reflect(where U: core::ops::Add<T>)]
2797        struct Foo<T, U>(T, U);
2798
2799        #[allow(
2800            clippy::allow_attributes,
2801            dead_code,
2802            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
2803        )]
2804        #[derive(Reflect)]
2805        struct Baz {
2806            a: Foo<i32, i32>,
2807            b: Foo<u32, u32>,
2808        }
2809
2810        assert_impl_all!(Foo<i32, i32>: Reflect);
2811        assert_not_impl_all!(Foo<i32, usize>: Reflect);
2812    }
2813
2814    #[test]
2815    fn should_allow_custom_where_with_assoc_type() {
2816        trait Trait {
2817            type Assoc;
2818        }
2819
2820        // We don't need `T` to be `Reflect` since we only care about `T::Assoc`
2821        #[derive(Reflect)]
2822        #[reflect(where T::Assoc: core::fmt::Display)]
2823        struct Foo<T: Trait>(T::Assoc);
2824
2825        #[derive(TypePath)]
2826        struct Bar;
2827
2828        impl Trait for Bar {
2829            type Assoc = usize;
2830        }
2831
2832        #[derive(TypePath)]
2833        struct Baz;
2834
2835        impl Trait for Baz {
2836            type Assoc = (f32, f32);
2837        }
2838
2839        assert_impl_all!(Foo<Bar>: Reflect);
2840        assert_not_impl_all!(Foo<Baz>: Reflect);
2841    }
2842
2843    #[test]
2844    fn should_allow_empty_enums() {
2845        #[derive(Reflect)]
2846        enum Empty {}
2847
2848        assert_impl_all!(Empty: Reflect);
2849    }
2850
2851    #[test]
2852    fn recursive_typed_storage_does_not_hang() {
2853        #[derive(Reflect)]
2854        struct Recurse<T>(T);
2855
2856        let _ = <Recurse<Recurse<()>> as Typed>::type_info();
2857        let _ = <Recurse<Recurse<()>> as TypePath>::type_path();
2858
2859        #[derive(Reflect)]
2860        #[reflect(no_field_bounds)]
2861        struct SelfRecurse {
2862            recurse: Vec<SelfRecurse>,
2863        }
2864
2865        let _ = <SelfRecurse as Typed>::type_info();
2866        let _ = <SelfRecurse as TypePath>::type_path();
2867
2868        #[derive(Reflect)]
2869        #[reflect(no_field_bounds)]
2870        enum RecurseA {
2871            Recurse(RecurseB),
2872        }
2873
2874        #[derive(Reflect)]
2875        // `#[reflect(no_field_bounds)]` not needed since already added to `RecurseA`
2876        struct RecurseB {
2877            vector: Vec<RecurseA>,
2878        }
2879
2880        let _ = <RecurseA as Typed>::type_info();
2881        let _ = <RecurseA as TypePath>::type_path();
2882        let _ = <RecurseB as Typed>::type_info();
2883        let _ = <RecurseB as TypePath>::type_path();
2884    }
2885
2886    #[test]
2887    fn recursive_registration_does_not_hang() {
2888        #[derive(Reflect)]
2889        struct Recurse<T>(T);
2890
2891        let mut registry = TypeRegistry::empty();
2892
2893        registry.register::<Recurse<Recurse<()>>>();
2894
2895        #[derive(Reflect)]
2896        #[reflect(no_field_bounds)]
2897        struct SelfRecurse {
2898            recurse: Vec<SelfRecurse>,
2899        }
2900
2901        registry.register::<SelfRecurse>();
2902
2903        #[derive(Reflect)]
2904        #[reflect(no_field_bounds)]
2905        enum RecurseA {
2906            Recurse(RecurseB),
2907        }
2908
2909        #[derive(Reflect)]
2910        struct RecurseB {
2911            vector: Vec<RecurseA>,
2912        }
2913
2914        registry.register::<RecurseA>();
2915        assert!(registry.contains(TypeId::of::<RecurseA>()));
2916        assert!(registry.contains(TypeId::of::<RecurseB>()));
2917    }
2918
2919    #[test]
2920    fn can_opt_out_type_path() {
2921        #[derive(Reflect)]
2922        #[reflect(type_path = false)]
2923        struct Foo<T> {
2924            #[reflect(ignore)]
2925            _marker: PhantomData<T>,
2926        }
2927
2928        struct NotTypePath;
2929
2930        impl<T: 'static> TypePath for Foo<T> {
2931            fn type_path() -> &'static str {
2932                core::any::type_name::<Self>()
2933            }
2934
2935            fn short_type_path() -> &'static str {
2936                static CELL: GenericTypePathCell = GenericTypePathCell::new();
2937                CELL.get_or_insert::<Self, _>(|| ShortName::of::<Self>().to_string())
2938            }
2939
2940            fn type_ident() -> Option<&'static str> {
2941                Some("Foo")
2942            }
2943
2944            fn crate_name() -> Option<&'static str> {
2945                Some("bevy_reflect")
2946            }
2947
2948            fn module_path() -> Option<&'static str> {
2949                Some("bevy_reflect::tests")
2950            }
2951        }
2952
2953        // Can use `TypePath`
2954        let path = <Foo<NotTypePath> as TypePath>::type_path();
2955        assert_eq!("bevy_reflect::tests::can_opt_out_type_path::Foo<bevy_reflect::tests::can_opt_out_type_path::NotTypePath>", path);
2956
2957        // Can register the type
2958        let mut registry = TypeRegistry::default();
2959        registry.register::<Foo<NotTypePath>>();
2960
2961        let registration = registry.get(TypeId::of::<Foo<NotTypePath>>()).unwrap();
2962        assert_eq!(
2963            "Foo<NotTypePath>",
2964            registration.type_info().type_path_table().short_path()
2965        );
2966    }
2967
2968    #[test]
2969    fn dynamic_types_debug_format() {
2970        #[derive(Debug, Reflect)]
2971        struct TestTupleStruct(u32);
2972
2973        #[derive(Debug, Reflect)]
2974        enum TestEnum {
2975            A(u32),
2976            B,
2977        }
2978
2979        #[derive(Debug, Reflect)]
2980        // test DynamicStruct
2981        struct TestStruct {
2982            // test DynamicTuple
2983            tuple: (u32, u32),
2984            // test DynamicTupleStruct
2985            tuple_struct: TestTupleStruct,
2986            // test DynamicList
2987            list: Vec<u32>,
2988            // test DynamicArray
2989            array: [u32; 3],
2990            // test DynamicEnum
2991            e: TestEnum,
2992            // test DynamicMap
2993            map: HashMap<u32, u32>,
2994            // test reflected value
2995            value: u32,
2996        }
2997        let mut map = <HashMap<_, _>>::default();
2998        map.insert(9, 10);
2999        let mut test_struct: DynamicStruct = TestStruct {
3000            tuple: (0, 1),
3001            list: vec![2, 3, 4],
3002            array: [5, 6, 7],
3003            tuple_struct: TestTupleStruct(8),
3004            e: TestEnum::A(11),
3005            map,
3006            value: 12,
3007        }
3008        .to_dynamic_struct();
3009
3010        // test unknown DynamicStruct
3011        let mut test_unknown_struct = DynamicStruct::default();
3012        test_unknown_struct.insert("a", 13);
3013        test_struct.insert("unknown_struct", test_unknown_struct);
3014        // test unknown DynamicTupleStruct
3015        let mut test_unknown_tuple_struct = DynamicTupleStruct::default();
3016        test_unknown_tuple_struct.insert(14);
3017        test_struct.insert("unknown_tuplestruct", test_unknown_tuple_struct);
3018        assert_eq!(
3019            format!("{test_struct:?}"),
3020            "DynamicStruct(bevy_reflect::tests::TestStruct { \
3021                tuple: DynamicTuple((0, 1)), \
3022                tuple_struct: DynamicTupleStruct(bevy_reflect::tests::TestTupleStruct(8)), \
3023                list: DynamicList([2, 3, 4]), \
3024                array: DynamicArray([5, 6, 7]), \
3025                e: DynamicEnum(A(11)), \
3026                map: DynamicMap({9: 10}), \
3027                value: 12, \
3028                unknown_struct: DynamicStruct(_ { a: 13 }), \
3029                unknown_tuplestruct: DynamicTupleStruct(_(14)) \
3030            })"
3031        );
3032    }
3033
3034    #[test]
3035    fn assert_impl_reflect_macro_on_all() {
3036        struct Struct {
3037            foo: (),
3038        }
3039        struct TupleStruct(());
3040        enum Enum {
3041            Foo { foo: () },
3042            Bar(()),
3043        }
3044
3045        impl_reflect!(
3046            #[type_path = "my_crate::foo"]
3047            struct Struct {
3048                foo: (),
3049            }
3050        );
3051
3052        impl_reflect!(
3053            #[type_path = "my_crate::foo"]
3054            struct TupleStruct(());
3055        );
3056
3057        impl_reflect!(
3058            #[type_path = "my_crate::foo"]
3059            enum Enum {
3060                Foo { foo: () },
3061                Bar(()),
3062            }
3063        );
3064
3065        assert_impl_all!(Struct: Reflect);
3066        assert_impl_all!(TupleStruct: Reflect);
3067        assert_impl_all!(Enum: Reflect);
3068    }
3069
3070    #[test]
3071    fn should_reflect_remote_type() {
3072        mod external_crate {
3073            use alloc::string::String;
3074
3075            #[derive(Debug, Default)]
3076            pub struct TheirType {
3077                pub value: String,
3078            }
3079        }
3080
3081        // === Remote Wrapper === //
3082        #[reflect_remote(external_crate::TheirType)]
3083        #[derive(Debug, Default)]
3084        #[reflect(Debug, Default)]
3085        struct MyType {
3086            pub value: String,
3087        }
3088
3089        let mut patch = DynamicStruct::default();
3090        patch.set_represented_type(Some(MyType::type_info()));
3091        patch.insert("value", "Goodbye".to_string());
3092
3093        let mut data = MyType(external_crate::TheirType {
3094            value: "Hello".to_string(),
3095        });
3096
3097        assert_eq!("Hello", data.0.value);
3098        data.apply(&patch);
3099        assert_eq!("Goodbye", data.0.value);
3100
3101        // === Struct Container === //
3102        #[derive(Reflect, Debug)]
3103        #[reflect(from_reflect = false)]
3104        struct ContainerStruct {
3105            #[reflect(remote = MyType)]
3106            their_type: external_crate::TheirType,
3107        }
3108
3109        let mut patch = DynamicStruct::default();
3110        patch.set_represented_type(Some(ContainerStruct::type_info()));
3111        patch.insert(
3112            "their_type",
3113            MyType(external_crate::TheirType {
3114                value: "Goodbye".to_string(),
3115            }),
3116        );
3117
3118        let mut data = ContainerStruct {
3119            their_type: external_crate::TheirType {
3120                value: "Hello".to_string(),
3121            },
3122        };
3123
3124        assert_eq!("Hello", data.their_type.value);
3125        data.apply(&patch);
3126        assert_eq!("Goodbye", data.their_type.value);
3127
3128        // === Tuple Struct Container === //
3129        #[derive(Reflect, Debug)]
3130        struct ContainerTupleStruct(#[reflect(remote = MyType)] external_crate::TheirType);
3131
3132        let mut patch = DynamicTupleStruct::default();
3133        patch.set_represented_type(Some(ContainerTupleStruct::type_info()));
3134        patch.insert(MyType(external_crate::TheirType {
3135            value: "Goodbye".to_string(),
3136        }));
3137
3138        let mut data = ContainerTupleStruct(external_crate::TheirType {
3139            value: "Hello".to_string(),
3140        });
3141
3142        assert_eq!("Hello", data.0.value);
3143        data.apply(&patch);
3144        assert_eq!("Goodbye", data.0.value);
3145    }
3146
3147    #[test]
3148    fn should_reflect_remote_value_type() {
3149        mod external_crate {
3150            use alloc::string::String;
3151
3152            #[derive(Clone, Debug, Default)]
3153            pub struct TheirType {
3154                pub value: String,
3155            }
3156        }
3157
3158        // === Remote Wrapper === //
3159        #[reflect_remote(external_crate::TheirType)]
3160        #[derive(Clone, Debug, Default)]
3161        #[reflect(opaque)]
3162        #[reflect(Debug, Default)]
3163        struct MyType {
3164            pub value: String,
3165        }
3166
3167        let mut data = MyType(external_crate::TheirType {
3168            value: "Hello".to_string(),
3169        });
3170
3171        let patch = MyType(external_crate::TheirType {
3172            value: "Goodbye".to_string(),
3173        });
3174
3175        assert_eq!("Hello", data.0.value);
3176        data.apply(&patch);
3177        assert_eq!("Goodbye", data.0.value);
3178
3179        // === Struct Container === //
3180        #[derive(Reflect, Debug)]
3181        #[reflect(from_reflect = false)]
3182        struct ContainerStruct {
3183            #[reflect(remote = MyType)]
3184            their_type: external_crate::TheirType,
3185        }
3186
3187        let mut patch = DynamicStruct::default();
3188        patch.set_represented_type(Some(ContainerStruct::type_info()));
3189        patch.insert(
3190            "their_type",
3191            MyType(external_crate::TheirType {
3192                value: "Goodbye".to_string(),
3193            }),
3194        );
3195
3196        let mut data = ContainerStruct {
3197            their_type: external_crate::TheirType {
3198                value: "Hello".to_string(),
3199            },
3200        };
3201
3202        assert_eq!("Hello", data.their_type.value);
3203        data.apply(&patch);
3204        assert_eq!("Goodbye", data.their_type.value);
3205
3206        // === Tuple Struct Container === //
3207        #[derive(Reflect, Debug)]
3208        struct ContainerTupleStruct(#[reflect(remote = MyType)] external_crate::TheirType);
3209
3210        let mut patch = DynamicTupleStruct::default();
3211        patch.set_represented_type(Some(ContainerTupleStruct::type_info()));
3212        patch.insert(MyType(external_crate::TheirType {
3213            value: "Goodbye".to_string(),
3214        }));
3215
3216        let mut data = ContainerTupleStruct(external_crate::TheirType {
3217            value: "Hello".to_string(),
3218        });
3219
3220        assert_eq!("Hello", data.0.value);
3221        data.apply(&patch);
3222        assert_eq!("Goodbye", data.0.value);
3223    }
3224
3225    #[test]
3226    fn should_reflect_remote_type_from_module() {
3227        mod wrapper {
3228            use super::*;
3229
3230            // We have to place this module internally to this one to get around the following error:
3231            // ```
3232            // error[E0433]: failed to resolve: use of undeclared crate or module `external_crate`
3233            // ```
3234            pub mod external_crate {
3235                use alloc::string::String;
3236
3237                #[allow(
3238                    clippy::allow_attributes,
3239                    dead_code,
3240                    reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
3241                )]
3242                pub struct TheirType {
3243                    pub value: String,
3244                }
3245            }
3246
3247            #[reflect_remote(external_crate::TheirType)]
3248            pub struct MyType {
3249                pub value: String,
3250            }
3251        }
3252
3253        #[allow(
3254            clippy::allow_attributes,
3255            dead_code,
3256            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
3257        )]
3258        #[derive(Reflect)]
3259        struct ContainerStruct {
3260            #[reflect(remote = wrapper::MyType)]
3261            their_type: wrapper::external_crate::TheirType,
3262        }
3263    }
3264
3265    #[test]
3266    fn should_reflect_remote_enum() {
3267        mod external_crate {
3268            use alloc::string::String;
3269
3270            #[derive(Debug, PartialEq, Eq)]
3271            pub enum TheirType {
3272                Unit,
3273                Tuple(usize),
3274                Struct { value: String },
3275            }
3276        }
3277
3278        // === Remote Wrapper === //
3279        #[reflect_remote(external_crate::TheirType)]
3280        #[derive(Debug)]
3281        #[reflect(Debug)]
3282        enum MyType {
3283            Unit,
3284            Tuple(usize),
3285            Struct { value: String },
3286        }
3287
3288        let mut patch = DynamicEnum::from(MyType(external_crate::TheirType::Tuple(123)));
3289
3290        let mut data = MyType(external_crate::TheirType::Unit);
3291
3292        assert_eq!(external_crate::TheirType::Unit, data.0);
3293        data.apply(&patch);
3294        assert_eq!(external_crate::TheirType::Tuple(123), data.0);
3295
3296        patch = DynamicEnum::from(MyType(external_crate::TheirType::Struct {
3297            value: "Hello world!".to_string(),
3298        }));
3299
3300        data.apply(&patch);
3301        assert_eq!(
3302            external_crate::TheirType::Struct {
3303                value: "Hello world!".to_string()
3304            },
3305            data.0
3306        );
3307
3308        // === Enum Container === //
3309        #[derive(Reflect, Debug, PartialEq)]
3310        enum ContainerEnum {
3311            Foo,
3312            Bar {
3313                #[reflect(remote = MyType)]
3314                their_type: external_crate::TheirType,
3315            },
3316        }
3317
3318        let patch = DynamicEnum::from(ContainerEnum::Bar {
3319            their_type: external_crate::TheirType::Tuple(123),
3320        });
3321
3322        let mut data = ContainerEnum::Foo;
3323
3324        assert_eq!(ContainerEnum::Foo, data);
3325        data.apply(&patch);
3326        assert_eq!(
3327            ContainerEnum::Bar {
3328                their_type: external_crate::TheirType::Tuple(123)
3329            },
3330            data
3331        );
3332    }
3333
3334    #[test]
3335    fn should_reflect_nested_remote_type() {
3336        mod external_crate {
3337            pub struct TheirOuter<T> {
3338                pub a: TheirInner<T>,
3339                pub b: TheirInner<bool>,
3340            }
3341
3342            pub struct TheirInner<T>(pub T);
3343        }
3344
3345        #[reflect_remote(external_crate::TheirOuter<T>)]
3346        struct MyOuter<T: FromReflect + Reflectable> {
3347            #[reflect(remote = MyInner<T>)]
3348            pub a: external_crate::TheirInner<T>,
3349            #[reflect(remote = MyInner<bool>)]
3350            pub b: external_crate::TheirInner<bool>,
3351        }
3352
3353        #[reflect_remote(external_crate::TheirInner<T>)]
3354        struct MyInner<T: FromReflect>(pub T);
3355
3356        let mut patch = DynamicStruct::default();
3357        patch.set_represented_type(Some(MyOuter::<i32>::type_info()));
3358        patch.insert("a", MyInner(external_crate::TheirInner(321_i32)));
3359        patch.insert("b", MyInner(external_crate::TheirInner(true)));
3360
3361        let mut data = MyOuter(external_crate::TheirOuter {
3362            a: external_crate::TheirInner(123_i32),
3363            b: external_crate::TheirInner(false),
3364        });
3365
3366        assert_eq!(123, data.0.a.0);
3367        assert!(!data.0.b.0);
3368        data.apply(&patch);
3369        assert_eq!(321, data.0.a.0);
3370        assert!(data.0.b.0);
3371    }
3372
3373    #[test]
3374    fn should_reflect_nested_remote_enum() {
3375        mod external_crate {
3376            use core::fmt::Debug;
3377
3378            #[derive(Debug)]
3379            pub enum TheirOuter<T: Debug> {
3380                Unit,
3381                Tuple(TheirInner<T>),
3382                Struct { value: TheirInner<T> },
3383            }
3384            #[derive(Debug)]
3385            pub enum TheirInner<T: Debug> {
3386                Unit,
3387                Tuple(T),
3388                Struct { value: T },
3389            }
3390        }
3391
3392        #[reflect_remote(external_crate::TheirOuter<T>)]
3393        #[derive(Debug)]
3394        enum MyOuter<T: FromReflect + Reflectable + Debug> {
3395            Unit,
3396            Tuple(#[reflect(remote = MyInner<T>)] external_crate::TheirInner<T>),
3397            Struct {
3398                #[reflect(remote = MyInner<T>)]
3399                value: external_crate::TheirInner<T>,
3400            },
3401        }
3402
3403        #[reflect_remote(external_crate::TheirInner<T>)]
3404        #[derive(Debug)]
3405        enum MyInner<T: FromReflect + Debug> {
3406            Unit,
3407            Tuple(T),
3408            Struct { value: T },
3409        }
3410
3411        let mut patch = DynamicEnum::default();
3412        let mut value = DynamicStruct::default();
3413        value.insert("value", MyInner(external_crate::TheirInner::Tuple(123)));
3414        patch.set_variant("Struct", value);
3415
3416        let mut data = MyOuter(external_crate::TheirOuter::<i32>::Unit);
3417
3418        assert!(matches!(
3419            data,
3420            MyOuter(external_crate::TheirOuter::<i32>::Unit)
3421        ));
3422        data.apply(&patch);
3423        assert!(matches!(
3424            data,
3425            MyOuter(external_crate::TheirOuter::Struct {
3426                value: external_crate::TheirInner::Tuple(123)
3427            })
3428        ));
3429    }
3430
3431    #[test]
3432    fn should_take_remote_type() {
3433        mod external_crate {
3434            use alloc::string::String;
3435
3436            #[derive(Debug, Default, PartialEq, Eq)]
3437            pub struct TheirType {
3438                pub value: String,
3439            }
3440        }
3441
3442        // === Remote Wrapper === //
3443        #[reflect_remote(external_crate::TheirType)]
3444        #[derive(Debug, Default)]
3445        #[reflect(Debug, Default)]
3446        struct MyType {
3447            pub value: String,
3448        }
3449
3450        let input: Box<dyn Reflect> = Box::new(MyType(external_crate::TheirType {
3451            value: "Hello".to_string(),
3452        }));
3453
3454        let output: external_crate::TheirType = input
3455            .take()
3456            .expect("should downcast to `external_crate::TheirType`");
3457        assert_eq!(
3458            external_crate::TheirType {
3459                value: "Hello".to_string(),
3460            },
3461            output
3462        );
3463    }
3464
3465    #[test]
3466    fn should_try_take_remote_type() {
3467        mod external_crate {
3468            use alloc::string::String;
3469
3470            #[derive(Debug, Default, PartialEq, Eq)]
3471            pub struct TheirType {
3472                pub value: String,
3473            }
3474        }
3475
3476        // === Remote Wrapper === //
3477        #[reflect_remote(external_crate::TheirType)]
3478        #[derive(Debug, Default)]
3479        #[reflect(Debug, Default)]
3480        struct MyType {
3481            pub value: String,
3482        }
3483
3484        let input: Box<dyn PartialReflect> = Box::new(MyType(external_crate::TheirType {
3485            value: "Hello".to_string(),
3486        }));
3487
3488        let output: external_crate::TheirType = input
3489            .try_take()
3490            .expect("should downcast to `external_crate::TheirType`");
3491        assert_eq!(
3492            external_crate::TheirType {
3493                value: "Hello".to_string(),
3494            },
3495            output,
3496        );
3497    }
3498
3499    #[test]
3500    fn should_take_nested_remote_type() {
3501        mod external_crate {
3502            #[derive(PartialEq, Eq, Debug)]
3503            pub struct TheirOuter<T> {
3504                pub inner: TheirInner<T>,
3505            }
3506            #[derive(PartialEq, Eq, Debug)]
3507            pub struct TheirInner<T>(pub T);
3508        }
3509
3510        #[reflect_remote(external_crate::TheirOuter<T>)]
3511        struct MyOuter<T: FromReflect + Reflectable> {
3512            #[reflect(remote = MyInner<T>)]
3513            pub inner: external_crate::TheirInner<T>,
3514        }
3515
3516        #[reflect_remote(external_crate::TheirInner<T>)]
3517        struct MyInner<T: FromReflect>(pub T);
3518
3519        let input: Box<dyn Reflect> = Box::new(MyOuter(external_crate::TheirOuter {
3520            inner: external_crate::TheirInner(123),
3521        }));
3522
3523        let output: external_crate::TheirOuter<i32> = input
3524            .take()
3525            .expect("should downcast to `external_crate::TheirOuter`");
3526        assert_eq!(
3527            external_crate::TheirOuter {
3528                inner: external_crate::TheirInner(123),
3529            },
3530            output
3531        );
3532    }
3533
3534    // https://github.com/bevyengine/bevy/issues/19017
3535    #[test]
3536    fn should_serialize_opaque_remote_type() {
3537        mod external_crate {
3538            use serde::{Deserialize, Serialize};
3539            #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
3540            pub struct Vector2<T>(pub [T; 2]);
3541        }
3542
3543        #[reflect_remote(external_crate::Vector2<i32>)]
3544        #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
3545        #[reflect(Serialize, Deserialize)]
3546        #[reflect(opaque)]
3547        struct Vector2Wrapper([i32; 2]);
3548
3549        #[derive(Reflect, Debug, PartialEq)]
3550        struct Point(#[reflect(remote = Vector2Wrapper)] external_crate::Vector2<i32>);
3551
3552        let point = Point(external_crate::Vector2([1, 2]));
3553
3554        let mut registry = TypeRegistry::new();
3555        registry.register::<Point>();
3556        registry.register::<Vector2Wrapper>();
3557
3558        let serializer = ReflectSerializer::new(&point, &registry);
3559        let serialized = ron::to_string(&serializer).unwrap();
3560        assert_eq!(serialized, r#"{"bevy_reflect::tests::Point":((((1,2))))}"#);
3561
3562        let mut deserializer = Deserializer::from_str(&serialized).unwrap();
3563        let reflect_deserializer = ReflectDeserializer::new(&registry);
3564        let deserialized = reflect_deserializer.deserialize(&mut deserializer).unwrap();
3565        let point = <Point as FromReflect>::from_reflect(&*deserialized).unwrap();
3566        assert_eq!(point, Point(external_crate::Vector2([1, 2])));
3567    }
3568
3569    #[cfg(feature = "auto_register")]
3570    mod auto_register_reflect {
3571        use super::*;
3572
3573        #[test]
3574        fn should_ignore_auto_reflect_registration() {
3575            #[derive(Reflect)]
3576            #[reflect(no_auto_register)]
3577            struct NoAutomaticStruct {
3578                a: usize,
3579            }
3580
3581            let mut registry = TypeRegistry::default();
3582            registry.register_derived_types();
3583
3584            assert!(!registry.contains(TypeId::of::<NoAutomaticStruct>()));
3585        }
3586
3587        #[test]
3588        fn should_auto_register_reflect_for_all_supported_types() {
3589            // Struct
3590            #[derive(Reflect)]
3591            struct StructReflect {
3592                a: usize,
3593            }
3594
3595            // ZST struct
3596            #[derive(Reflect)]
3597            struct ZSTStructReflect;
3598
3599            // Tuple struct
3600            #[derive(Reflect)]
3601            struct TupleStructReflect(pub u32);
3602
3603            // Enum
3604            #[derive(Reflect)]
3605            enum EnumReflect {
3606                A,
3607                B,
3608            }
3609
3610            // ZST enum
3611            #[derive(Reflect)]
3612            enum ZSTEnumReflect {}
3613
3614            // Opaque struct
3615            #[derive(Reflect, Clone)]
3616            #[reflect(opaque)]
3617            struct OpaqueStructReflect {
3618                _a: usize,
3619            }
3620
3621            // ZST opaque struct
3622            #[derive(Reflect, Clone)]
3623            #[reflect(opaque)]
3624            struct ZSTOpaqueStructReflect;
3625
3626            let mut registry = TypeRegistry::default();
3627            registry.register_derived_types();
3628
3629            assert!(registry.contains(TypeId::of::<StructReflect>()));
3630            assert!(registry.contains(TypeId::of::<ZSTStructReflect>()));
3631            assert!(registry.contains(TypeId::of::<TupleStructReflect>()));
3632            assert!(registry.contains(TypeId::of::<EnumReflect>()));
3633            assert!(registry.contains(TypeId::of::<ZSTEnumReflect>()));
3634            assert!(registry.contains(TypeId::of::<OpaqueStructReflect>()));
3635            assert!(registry.contains(TypeId::of::<ZSTOpaqueStructReflect>()));
3636        }
3637
3638        #[test]
3639        fn type_data_dependency() {
3640            #[derive(Reflect)]
3641            #[reflect(A)]
3642            struct X;
3643
3644            #[derive(Clone)]
3645            struct ReflectA;
3646
3647            impl<T> FromType<T> for ReflectA {
3648                fn from_type() -> Self {
3649                    ReflectA
3650                }
3651
3652                fn insert_dependencies(type_registration: &mut TypeRegistration) {
3653                    type_registration.insert(ReflectB);
3654                }
3655            }
3656
3657            #[derive(Clone)]
3658            struct ReflectB;
3659
3660            let mut registry = TypeRegistry::new();
3661            registry.register::<X>();
3662
3663            let registration = registry.get(TypeId::of::<X>()).unwrap();
3664            assert!(registration.data::<ReflectA>().is_some());
3665            assert!(registration.data::<ReflectB>().is_some());
3666        }
3667    }
3668
3669    #[cfg(feature = "glam")]
3670    mod glam {
3671        use super::*;
3672        use ::glam::{quat, vec3, Quat, Vec3};
3673
3674        #[test]
3675        fn quat_serialization() {
3676            let q = quat(1.0, 2.0, 3.0, 4.0);
3677
3678            let mut registry = TypeRegistry::default();
3679            registry.register::<f32>();
3680            registry.register::<Quat>();
3681
3682            let ser = ReflectSerializer::new(&q, &registry);
3683
3684            let config = PrettyConfig::default()
3685                .new_line(String::from("\n"))
3686                .indentor(String::from("    "));
3687            let output = to_string_pretty(&ser, config).unwrap();
3688            let expected = r#"
3689{
3690    "glam::Quat": (1.0, 2.0, 3.0, 4.0),
3691}"#;
3692
3693            assert_eq!(expected, format!("\n{output}"));
3694        }
3695
3696        #[test]
3697        fn quat_deserialization() {
3698            let data = r#"
3699{
3700    "glam::Quat": (1.0, 2.0, 3.0, 4.0),
3701}"#;
3702
3703            let mut registry = TypeRegistry::default();
3704            registry.register::<Quat>();
3705            registry.register::<f32>();
3706
3707            let de = ReflectDeserializer::new(&registry);
3708
3709            let mut deserializer =
3710                Deserializer::from_str(data).expect("Failed to acquire deserializer");
3711
3712            let dynamic_struct = de
3713                .deserialize(&mut deserializer)
3714                .expect("Failed to deserialize");
3715
3716            let mut result = Quat::default();
3717
3718            result.apply(dynamic_struct.as_partial_reflect());
3719
3720            assert_eq!(result, quat(1.0, 2.0, 3.0, 4.0));
3721        }
3722
3723        #[test]
3724        fn vec3_serialization() {
3725            let v = vec3(12.0, 3.0, -6.9);
3726
3727            let mut registry = TypeRegistry::default();
3728            registry.register::<f32>();
3729            registry.register::<Vec3>();
3730
3731            let ser = ReflectSerializer::new(&v, &registry);
3732
3733            let config = PrettyConfig::default()
3734                .new_line(String::from("\n"))
3735                .indentor(String::from("    "));
3736            let output = to_string_pretty(&ser, config).unwrap();
3737            let expected = r#"
3738{
3739    "glam::Vec3": (12.0, 3.0, -6.9),
3740}"#;
3741
3742            assert_eq!(expected, format!("\n{output}"));
3743        }
3744
3745        #[test]
3746        fn vec3_deserialization() {
3747            let data = r#"
3748{
3749    "glam::Vec3": (12.0, 3.0, -6.9),
3750}"#;
3751
3752            let mut registry = TypeRegistry::default();
3753            registry.add_registration(Vec3::get_type_registration());
3754            registry.add_registration(f32::get_type_registration());
3755
3756            let de = ReflectDeserializer::new(&registry);
3757
3758            let mut deserializer =
3759                Deserializer::from_str(data).expect("Failed to acquire deserializer");
3760
3761            let dynamic_struct = de
3762                .deserialize(&mut deserializer)
3763                .expect("Failed to deserialize");
3764
3765            let mut result = Vec3::default();
3766
3767            result.apply(dynamic_struct.as_partial_reflect());
3768
3769            assert_eq!(result, vec3(12.0, 3.0, -6.9));
3770        }
3771
3772        #[test]
3773        fn vec3_field_access() {
3774            let mut v = vec3(1.0, 2.0, 3.0);
3775
3776            assert_eq!(*v.get_field::<f32>("x").unwrap(), 1.0);
3777
3778            *v.get_field_mut::<f32>("y").unwrap() = 6.0;
3779
3780            assert_eq!(v.y, 6.0);
3781        }
3782
3783        #[test]
3784        fn vec3_path_access() {
3785            let mut v = vec3(1.0, 2.0, 3.0);
3786
3787            assert_eq!(
3788                *v.reflect_path("x")
3789                    .unwrap()
3790                    .try_downcast_ref::<f32>()
3791                    .unwrap(),
3792                1.0
3793            );
3794
3795            *v.reflect_path_mut("y")
3796                .unwrap()
3797                .try_downcast_mut::<f32>()
3798                .unwrap() = 6.0;
3799
3800            assert_eq!(v.y, 6.0);
3801        }
3802
3803        #[test]
3804        fn vec3_apply_dynamic() {
3805            let mut v = vec3(3.0, 3.0, 3.0);
3806
3807            let mut d = DynamicStruct::default();
3808            d.insert("x", 4.0f32);
3809            d.insert("y", 2.0f32);
3810            d.insert("z", 1.0f32);
3811
3812            v.apply(&d);
3813
3814            assert_eq!(v, vec3(4.0, 2.0, 1.0));
3815        }
3816    }
3817}