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