Skip to main content

bevy_reflect/
lib.rs

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