bevy_reflect/
lib.rs

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