bevy_reflect/
lib.rs

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