bevy_reflect/
reflect.rs

1use crate::{
2    array_debug, enum_debug, list_debug, map_debug, set_debug, struct_debug, tuple_debug,
3    tuple_struct_debug, DynamicTypePath, DynamicTyped, OpaqueInfo, ReflectCloneError, ReflectKind,
4    ReflectKindMismatchError, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, Typed,
5};
6use alloc::borrow::Cow;
7use alloc::boxed::Box;
8use alloc::string::ToString;
9use core::{
10    any::{Any, TypeId},
11    fmt::Debug,
12};
13
14use thiserror::Error;
15
16use crate::utility::NonGenericTypeInfoCell;
17
18/// A enumeration of all error outcomes that might happen when running [`try_apply`](PartialReflect::try_apply).
19#[derive(Error, Debug)]
20pub enum ApplyError {
21    #[error("attempted to apply `{from_kind}` to `{to_kind}`")]
22    /// Attempted to apply the wrong [kind](ReflectKind) to a type, e.g. a struct to an enum.
23    MismatchedKinds {
24        from_kind: ReflectKind,
25        to_kind: ReflectKind,
26    },
27
28    #[error("enum variant `{variant_name}` doesn't have a field named `{field_name}`")]
29    /// Enum variant that we tried to apply to was missing a field.
30    MissingEnumField {
31        variant_name: Box<str>,
32        field_name: Box<str>,
33    },
34
35    #[error("`{from_type}` is not `{to_type}`")]
36    /// Tried to apply incompatible types.
37    MismatchedTypes {
38        from_type: Box<str>,
39        to_type: Box<str>,
40    },
41
42    #[error("attempted to apply type with {from_size} size to a type with {to_size} size")]
43    /// Attempted to apply to types with mismatched sizes, e.g. a [u8; 4] to [u8; 3].
44    DifferentSize { from_size: usize, to_size: usize },
45
46    #[error("variant with name `{variant_name}` does not exist on enum `{enum_name}`")]
47    /// The enum we tried to apply to didn't contain a variant with the give name.
48    UnknownVariant {
49        enum_name: Box<str>,
50        variant_name: Box<str>,
51    },
52}
53
54impl From<ReflectKindMismatchError> for ApplyError {
55    fn from(value: ReflectKindMismatchError) -> Self {
56        Self::MismatchedKinds {
57            from_kind: value.received,
58            to_kind: value.expected,
59        }
60    }
61}
62
63/// The foundational trait of [`bevy_reflect`], used for accessing and modifying data dynamically.
64///
65/// This is a supertrait of [`Reflect`],
66/// meaning any type which implements `Reflect` implements `PartialReflect` by definition.
67///
68/// It's recommended to use [the derive macro for `Reflect`] rather than manually implementing this trait.
69/// Doing so will automatically implement this trait as well as many other useful traits for reflection,
70/// including one of the appropriate subtraits: [`Struct`], [`TupleStruct`] or [`Enum`].
71///
72/// See the [crate-level documentation] to see how this trait and its subtraits can be used.
73///
74/// [`bevy_reflect`]: crate
75/// [the derive macro for `Reflect`]: bevy_reflect_derive::Reflect
76/// [`Struct`]: crate::Struct
77/// [`TupleStruct`]: crate::TupleStruct
78/// [`Enum`]: crate::Enum
79/// [crate-level documentation]: crate
80#[diagnostic::on_unimplemented(
81    message = "`{Self}` does not implement `PartialReflect` so cannot be introspected",
82    note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
83)]
84pub trait PartialReflect: DynamicTypePath + Send + Sync
85where
86    // NB: we don't use `Self: Any` since for downcasting, `Reflect` should be used.
87    Self: 'static,
88{
89    /// Returns the [`TypeInfo`] of the type _represented_ by this value.
90    ///
91    /// For most types, this will simply return their own `TypeInfo`.
92    /// However, for dynamic types, such as [`DynamicStruct`] or [`DynamicList`],
93    /// this will return the type they represent
94    /// (or `None` if they don't represent any particular type).
95    ///
96    /// This method is great if you have an instance of a type or a `dyn Reflect`,
97    /// and want to access its [`TypeInfo`]. However, if this method is to be called
98    /// frequently, consider using [`TypeRegistry::get_type_info`] as it can be more
99    /// performant for such use cases.
100    ///
101    /// [`DynamicStruct`]: crate::DynamicStruct
102    /// [`DynamicList`]: crate::DynamicList
103    /// [`TypeRegistry::get_type_info`]: crate::TypeRegistry::get_type_info
104    fn get_represented_type_info(&self) -> Option<&'static TypeInfo>;
105
106    /// Casts this type to a boxed, reflected value.
107    ///
108    /// This is useful for coercing trait objects.
109    fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect>;
110
111    /// Casts this type to a reflected value.
112    ///
113    /// This is useful for coercing trait objects.
114    fn as_partial_reflect(&self) -> &dyn PartialReflect;
115
116    /// Casts this type to a mutable, reflected value.
117    ///
118    /// This is useful for coercing trait objects.
119    fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect;
120
121    /// Attempts to cast this type to a boxed, [fully-reflected] value.
122    ///
123    /// [fully-reflected]: Reflect
124    fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>;
125
126    /// Attempts to cast this type to a [fully-reflected] value.
127    ///
128    /// [fully-reflected]: Reflect
129    fn try_as_reflect(&self) -> Option<&dyn Reflect>;
130
131    /// Attempts to cast this type to a mutable, [fully-reflected] value.
132    ///
133    /// [fully-reflected]: Reflect
134    fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect>;
135
136    /// Applies a reflected value to this value.
137    ///
138    /// If a type implements an [introspection subtrait], then the semantics of this
139    /// method are as follows:
140    /// - If `T` is a [`Struct`], then the value of each named field of `value` is
141    ///   applied to the corresponding named field of `self`. Fields which are
142    ///   not present in both structs are ignored.
143    /// - If `T` is a [`TupleStruct`] or [`Tuple`], then the value of each
144    ///   numbered field is applied to the corresponding numbered field of
145    ///   `self.` Fields which are not present in both values are ignored.
146    /// - If `T` is an [`Enum`], then the variant of `self` is `updated` to match
147    ///   the variant of `value`. The corresponding fields of that variant are
148    ///   applied from `value` onto `self`. Fields which are not present in both
149    ///   values are ignored.
150    /// - If `T` is a [`List`] or [`Array`], then each element of `value` is applied
151    ///   to the corresponding element of `self`. Up to `self.len()` items are applied,
152    ///   and excess elements in `value` are appended to `self`.
153    /// - If `T` is a [`Map`], then for each key in `value`, the associated
154    ///   value is applied to the value associated with the same key in `self`.
155    ///   Keys which are not present in `self` are inserted.
156    /// - If `T` is none of these, then `value` is downcast to `T`, cloned, and
157    ///   assigned to `self`.
158    ///
159    /// Note that `Reflect` must be implemented manually for [`List`]s and
160    /// [`Map`]s in order to achieve the correct semantics, as derived
161    /// implementations will have the semantics for [`Struct`], [`TupleStruct`], [`Enum`]
162    /// or none of the above depending on the kind of type. For lists and maps, use the
163    /// [`list_apply`] and [`map_apply`] helper functions when implementing this method.
164    ///
165    /// [introspection subtrait]: crate#the-introspection-subtraits
166    /// [`Struct`]: crate::Struct
167    /// [`TupleStruct`]: crate::TupleStruct
168    /// [`Tuple`]: crate::Tuple
169    /// [`Enum`]: crate::Enum
170    /// [`List`]: crate::List
171    /// [`Array`]: crate::Array
172    /// [`Map`]: crate::Map
173    /// [`list_apply`]: crate::list_apply
174    /// [`map_apply`]: crate::map_apply
175    ///
176    /// # Panics
177    ///
178    /// Derived implementations of this method will panic:
179    /// - If the type of `value` is not of the same kind as `T` (e.g. if `T` is
180    ///   a `List`, while `value` is a `Struct`).
181    /// - If `T` is any complex type and the corresponding fields or elements of
182    ///   `self` and `value` are not of the same type.
183    /// - If `T` is an opaque type and `self` cannot be downcast to `T`
184    fn apply(&mut self, value: &dyn PartialReflect) {
185        PartialReflect::try_apply(self, value).unwrap();
186    }
187
188    /// Tries to [`apply`](PartialReflect::apply) a reflected value to this value.
189    ///
190    /// Functions the same as the [`apply`](PartialReflect::apply) function but returns an error instead of
191    /// panicking.
192    ///
193    /// # Handling Errors
194    ///
195    /// This function may leave `self` in a partially mutated state if a error was encountered on the way.
196    /// consider maintaining a cloned instance of this data you can switch to if a error is encountered.
197    fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError>;
198
199    /// Returns a zero-sized enumeration of "kinds" of type.
200    ///
201    /// See [`ReflectKind`].
202    fn reflect_kind(&self) -> ReflectKind {
203        self.reflect_ref().kind()
204    }
205
206    /// Returns an immutable enumeration of "kinds" of type.
207    ///
208    /// See [`ReflectRef`].
209    fn reflect_ref(&self) -> ReflectRef;
210
211    /// Returns a mutable enumeration of "kinds" of type.
212    ///
213    /// See [`ReflectMut`].
214    fn reflect_mut(&mut self) -> ReflectMut;
215
216    /// Returns an owned enumeration of "kinds" of type.
217    ///
218    /// See [`ReflectOwned`].
219    fn reflect_owned(self: Box<Self>) -> ReflectOwned;
220
221    /// Clones `Self` into its dynamic representation.
222    ///
223    /// For value types or types marked with `#[reflect_value]`,
224    /// this will simply return a clone of `Self`.
225    ///
226    /// Otherwise the associated dynamic type will be returned.
227    ///
228    /// For example, a [`List`] type will invoke [`List::clone_dynamic`], returning [`DynamicList`].
229    /// A [`Struct`] type will invoke [`Struct::clone_dynamic`], returning [`DynamicStruct`].
230    /// And so on.
231    ///
232    /// If the dynamic behavior is not desired, a concrete clone can be obtained using [`PartialReflect::reflect_clone`].
233    ///
234    /// # Example
235    ///
236    /// ```
237    /// # use bevy_reflect::{PartialReflect};
238    /// let value = (1, true, 3.14);
239    /// let cloned = value.clone_value();
240    /// assert!(cloned.is_dynamic())
241    /// ```
242    ///
243    /// [`List`]: crate::List
244    /// [`List::clone_dynamic`]: crate::List::clone_dynamic
245    /// [`DynamicList`]: crate::DynamicList
246    /// [`Struct`]: crate::Struct
247    /// [`Struct::clone_dynamic`]: crate::Struct::clone_dynamic
248    /// [`DynamicStruct`]: crate::DynamicStruct
249    #[deprecated(
250        since = "0.16.0",
251        note = "to clone reflected values, prefer using `reflect_clone`. To convert reflected values to dynamic ones, use `to_dynamic`."
252    )]
253    fn clone_value(&self) -> Box<dyn PartialReflect> {
254        self.to_dynamic()
255    }
256
257    /// Converts this reflected value into its dynamic representation based on its [kind].
258    ///
259    /// For example, a [`List`] type will internally invoke [`List::to_dynamic_list`], returning [`DynamicList`].
260    /// A [`Struct`] type will invoke [`Struct::to_dynamic_struct`], returning [`DynamicStruct`].
261    /// And so on.
262    ///
263    /// If the [kind] is [opaque], then the value will attempt to be cloned directly via [`reflect_clone`],
264    /// since opaque types do not have any standard dynamic representation.
265    ///
266    /// To attempt to clone the value directly such that it returns a concrete instance of this type,
267    /// use [`reflect_clone`].
268    ///
269    /// # Panics
270    ///
271    /// This method will panic if the [kind] is [opaque] and the call to [`reflect_clone`] fails.
272    ///
273    /// # Example
274    ///
275    /// ```
276    /// # use bevy_reflect::{PartialReflect};
277    /// let value = (1, true, 3.14);
278    /// let dynamic_value = value.to_dynamic();
279    /// assert!(dynamic_value.is_dynamic())
280    /// ```
281    ///
282    /// [kind]: PartialReflect::reflect_kind
283    /// [`List`]: crate::List
284    /// [`List::to_dynamic_list`]: crate::List::to_dynamic_list
285    /// [`DynamicList`]: crate::DynamicList
286    /// [`Struct`]: crate::Struct
287    /// [`Struct::to_dynamic_struct`]: crate::Struct::to_dynamic_struct
288    /// [`DynamicStruct`]: crate::DynamicStruct
289    /// [opaque]: crate::ReflectKind::Opaque
290    /// [`reflect_clone`]: PartialReflect::reflect_clone
291    fn to_dynamic(&self) -> Box<dyn PartialReflect> {
292        match self.reflect_ref() {
293            ReflectRef::Struct(dyn_struct) => Box::new(dyn_struct.to_dynamic_struct()),
294            ReflectRef::TupleStruct(dyn_tuple_struct) => {
295                Box::new(dyn_tuple_struct.to_dynamic_tuple_struct())
296            }
297            ReflectRef::Tuple(dyn_tuple) => Box::new(dyn_tuple.to_dynamic_tuple()),
298            ReflectRef::List(dyn_list) => Box::new(dyn_list.to_dynamic_list()),
299            ReflectRef::Array(dyn_array) => Box::new(dyn_array.to_dynamic_array()),
300            ReflectRef::Map(dyn_map) => Box::new(dyn_map.to_dynamic_map()),
301            ReflectRef::Set(dyn_set) => Box::new(dyn_set.to_dynamic_set()),
302            ReflectRef::Enum(dyn_enum) => Box::new(dyn_enum.to_dynamic_enum()),
303            #[cfg(feature = "functions")]
304            ReflectRef::Function(dyn_function) => Box::new(dyn_function.to_dynamic_function()),
305            ReflectRef::Opaque(value) => value.reflect_clone().unwrap().into_partial_reflect(),
306        }
307    }
308
309    /// Attempts to clone `Self` using reflection.
310    ///
311    /// Unlike [`to_dynamic`], which generally returns a dynamic representation of `Self`,
312    /// this method attempts create a clone of `Self` directly, if possible.
313    ///
314    /// If the clone cannot be performed, an appropriate [`ReflectCloneError`] is returned.
315    ///
316    /// # Example
317    ///
318    /// ```
319    /// # use bevy_reflect::PartialReflect;
320    /// let value = (1, true, 3.14);
321    /// let cloned = value.reflect_clone().unwrap();
322    /// assert!(cloned.is::<(i32, bool, f64)>())
323    /// ```
324    ///
325    /// [`to_dynamic`]: PartialReflect::to_dynamic
326    fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError> {
327        Err(ReflectCloneError::NotImplemented {
328            type_path: Cow::Owned(self.reflect_type_path().to_string()),
329        })
330    }
331
332    /// Returns a hash of the value (which includes the type).
333    ///
334    /// If the underlying type does not support hashing, returns `None`.
335    fn reflect_hash(&self) -> Option<u64> {
336        None
337    }
338
339    /// Returns a "partial equality" comparison result.
340    ///
341    /// If the underlying type does not support equality testing, returns `None`.
342    fn reflect_partial_eq(&self, _value: &dyn PartialReflect) -> Option<bool> {
343        None
344    }
345
346    /// Debug formatter for the value.
347    ///
348    /// Any value that is not an implementor of other `Reflect` subtraits
349    /// (e.g. [`List`], [`Map`]), will default to the format: `"Reflect(type_path)"`,
350    /// where `type_path` is the [type path] of the underlying type.
351    ///
352    /// [`List`]: crate::List
353    /// [`Map`]: crate::Map
354    /// [type path]: TypePath::type_path
355    fn debug(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
356        match self.reflect_ref() {
357            ReflectRef::Struct(dyn_struct) => struct_debug(dyn_struct, f),
358            ReflectRef::TupleStruct(dyn_tuple_struct) => tuple_struct_debug(dyn_tuple_struct, f),
359            ReflectRef::Tuple(dyn_tuple) => tuple_debug(dyn_tuple, f),
360            ReflectRef::List(dyn_list) => list_debug(dyn_list, f),
361            ReflectRef::Array(dyn_array) => array_debug(dyn_array, f),
362            ReflectRef::Map(dyn_map) => map_debug(dyn_map, f),
363            ReflectRef::Set(dyn_set) => set_debug(dyn_set, f),
364            ReflectRef::Enum(dyn_enum) => enum_debug(dyn_enum, f),
365            #[cfg(feature = "functions")]
366            ReflectRef::Function(dyn_function) => dyn_function.fmt(f),
367            ReflectRef::Opaque(_) => write!(f, "Reflect({})", self.reflect_type_path()),
368        }
369    }
370
371    /// Indicates whether or not this type is a _dynamic_ type.
372    ///
373    /// Dynamic types include the ones built-in to this [crate],
374    /// such as [`DynamicStruct`], [`DynamicList`], and [`DynamicTuple`].
375    /// However, they may be custom types used as proxies for other types
376    /// or to facilitate scripting capabilities.
377    ///
378    /// By default, this method will return `false`.
379    ///
380    /// [`DynamicStruct`]: crate::DynamicStruct
381    /// [`DynamicList`]: crate::DynamicList
382    /// [`DynamicTuple`]: crate::DynamicTuple
383    fn is_dynamic(&self) -> bool {
384        false
385    }
386}
387
388/// A core trait of [`bevy_reflect`], used for downcasting to concrete types.
389///
390/// This is a subtrait of [`PartialReflect`],
391/// meaning any type which implements `Reflect` implements `PartialReflect` by definition.
392///
393/// It's recommended to use [the derive macro] rather than manually implementing this trait.
394/// Doing so will automatically implement this trait, [`PartialReflect`], and many other useful traits for reflection,
395/// including one of the appropriate subtraits: [`Struct`], [`TupleStruct`] or [`Enum`].
396///
397/// If you need to use this trait as a generic bound along with other reflection traits,
398/// for your convenience, consider using [`Reflectable`] instead.
399///
400/// See the [crate-level documentation] to see how this trait can be used.
401///
402/// [`bevy_reflect`]: crate
403/// [the derive macro]: bevy_reflect_derive::Reflect
404/// [`Struct`]: crate::Struct
405/// [`TupleStruct`]: crate::TupleStruct
406/// [`Enum`]: crate::Enum
407/// [`Reflectable`]: crate::Reflectable
408/// [crate-level documentation]: crate
409#[diagnostic::on_unimplemented(
410    message = "`{Self}` does not implement `Reflect` so cannot be fully reflected",
411    note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
412)]
413pub trait Reflect: PartialReflect + DynamicTyped + Any {
414    /// Returns the value as a [`Box<dyn Any>`][core::any::Any].
415    ///
416    /// For remote wrapper types, this will return the remote type instead.
417    fn into_any(self: Box<Self>) -> Box<dyn Any>;
418
419    /// Returns the value as a [`&dyn Any`][core::any::Any].
420    ///
421    /// For remote wrapper types, this will return the remote type instead.
422    fn as_any(&self) -> &dyn Any;
423
424    /// Returns the value as a [`&mut dyn Any`][core::any::Any].
425    ///
426    /// For remote wrapper types, this will return the remote type instead.
427    fn as_any_mut(&mut self) -> &mut dyn Any;
428
429    /// Casts this type to a boxed, fully-reflected value.
430    fn into_reflect(self: Box<Self>) -> Box<dyn Reflect>;
431
432    /// Casts this type to a fully-reflected value.
433    fn as_reflect(&self) -> &dyn Reflect;
434
435    /// Casts this type to a mutable, fully-reflected value.
436    fn as_reflect_mut(&mut self) -> &mut dyn Reflect;
437
438    /// Performs a type-checked assignment of a reflected value to this value.
439    ///
440    /// If `value` does not contain a value of type `T`, returns an `Err`
441    /// containing the trait object.
442    fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>;
443}
444
445impl dyn PartialReflect {
446    /// Returns `true` if the underlying value represents a value of type `T`, or `false`
447    /// otherwise.
448    ///
449    /// Read `is` for more information on underlying values and represented types.
450    #[inline]
451    pub fn represents<T: Reflect + TypePath>(&self) -> bool {
452        self.get_represented_type_info()
453            .is_some_and(|t| t.type_path() == T::type_path())
454    }
455
456    /// Downcasts the value to type `T`, consuming the trait object.
457    ///
458    /// If the underlying value does not implement [`Reflect`]
459    /// or is not of type `T`, returns `Err(self)`.
460    ///
461    /// For remote types, `T` should be the type itself rather than the wrapper type.
462    pub fn try_downcast<T: Any>(
463        self: Box<dyn PartialReflect>,
464    ) -> Result<Box<T>, Box<dyn PartialReflect>> {
465        self.try_into_reflect()?
466            .downcast()
467            .map_err(PartialReflect::into_partial_reflect)
468    }
469
470    /// Downcasts the value to type `T`, unboxing and consuming the trait object.
471    ///
472    /// If the underlying value does not implement [`Reflect`]
473    /// or is not of type `T`, returns `Err(self)`.
474    ///
475    /// For remote types, `T` should be the type itself rather than the wrapper type.
476    pub fn try_take<T: Any>(self: Box<dyn PartialReflect>) -> Result<T, Box<dyn PartialReflect>> {
477        self.try_downcast().map(|value| *value)
478    }
479
480    /// Downcasts the value to type `T` by reference.
481    ///
482    /// If the underlying value does not implement [`Reflect`]
483    /// or is not of type `T`, returns [`None`].
484    ///
485    /// For remote types, `T` should be the type itself rather than the wrapper type.
486    pub fn try_downcast_ref<T: Any>(&self) -> Option<&T> {
487        self.try_as_reflect()?.downcast_ref()
488    }
489
490    /// Downcasts the value to type `T` by mutable reference.
491    ///
492    /// If the underlying value does not implement [`Reflect`]
493    /// or is not of type `T`, returns [`None`].
494    ///
495    /// For remote types, `T` should be the type itself rather than the wrapper type.
496    pub fn try_downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
497        self.try_as_reflect_mut()?.downcast_mut()
498    }
499}
500
501impl Debug for dyn PartialReflect {
502    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
503        self.debug(f)
504    }
505}
506
507// The following implementation never actually shadows the concrete TypePath implementation.
508// See the comment on `dyn Reflect`'s `TypePath` implementation.
509impl TypePath for dyn PartialReflect {
510    fn type_path() -> &'static str {
511        "dyn bevy_reflect::PartialReflect"
512    }
513
514    fn short_type_path() -> &'static str {
515        "dyn PartialReflect"
516    }
517}
518
519#[deny(rustdoc::broken_intra_doc_links)]
520impl dyn Reflect {
521    /// Downcasts the value to type `T`, consuming the trait object.
522    ///
523    /// If the underlying value is not of type `T`, returns `Err(self)`.
524    ///
525    /// For remote types, `T` should be the type itself rather than the wrapper type.
526    pub fn downcast<T: Any>(self: Box<dyn Reflect>) -> Result<Box<T>, Box<dyn Reflect>> {
527        if self.is::<T>() {
528            Ok(self.into_any().downcast().unwrap())
529        } else {
530            Err(self)
531        }
532    }
533
534    /// Downcasts the value to type `T`, unboxing and consuming the trait object.
535    ///
536    /// If the underlying value is not of type `T`, returns `Err(self)`.
537    ///
538    /// For remote types, `T` should be the type itself rather than the wrapper type.
539    pub fn take<T: Any>(self: Box<dyn Reflect>) -> Result<T, Box<dyn Reflect>> {
540        self.downcast::<T>().map(|value| *value)
541    }
542
543    /// Returns `true` if the underlying value is of type `T`, or `false`
544    /// otherwise.
545    ///
546    /// The underlying value is the concrete type that is stored in this `dyn` object;
547    /// it can be downcasted to. In the case that this underlying value "represents"
548    /// a different type, like the Dynamic\*\*\* types do, you can call `represents`
549    /// to determine what type they represent. Represented types cannot be downcasted
550    /// to, but you can use [`FromReflect`] to create a value of the represented type from them.
551    ///
552    /// For remote types, `T` should be the type itself rather than the wrapper type.
553    ///
554    /// [`FromReflect`]: crate::FromReflect
555    #[inline]
556    pub fn is<T: Any>(&self) -> bool {
557        self.as_any().type_id() == TypeId::of::<T>()
558    }
559
560    /// Downcasts the value to type `T` by reference.
561    ///
562    /// If the underlying value is not of type `T`, returns `None`.
563    ///
564    /// For remote types, `T` should be the type itself rather than the wrapper type.
565    #[inline]
566    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
567        self.as_any().downcast_ref::<T>()
568    }
569
570    /// Downcasts the value to type `T` by mutable reference.
571    ///
572    /// If the underlying value is not of type `T`, returns `None`.
573    ///
574    /// For remote types, `T` should be the type itself rather than the wrapper type.
575    #[inline]
576    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
577        self.as_any_mut().downcast_mut::<T>()
578    }
579}
580
581impl Debug for dyn Reflect {
582    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
583        self.debug(f)
584    }
585}
586
587impl Typed for dyn Reflect {
588    fn type_info() -> &'static TypeInfo {
589        static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
590        CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
591    }
592}
593
594// The following implementation never actually shadows the concrete `TypePath` implementation.
595// See this playground (https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=589064053f27bc100d90da89c6a860aa).
596impl TypePath for dyn Reflect {
597    fn type_path() -> &'static str {
598        "dyn bevy_reflect::Reflect"
599    }
600
601    fn short_type_path() -> &'static str {
602        "dyn Reflect"
603    }
604}
605
606macro_rules! impl_full_reflect {
607    ($(<$($id:ident),* $(,)?>)? for $ty:ty $(where $($tt:tt)*)?) => {
608        impl $(<$($id),*>)? $crate::Reflect for $ty $(where $($tt)*)? {
609            fn into_any(self: Box<Self>) -> Box<dyn ::core::any::Any> {
610                self
611            }
612
613            fn as_any(&self) -> &dyn ::core::any::Any {
614                self
615            }
616
617            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any {
618                self
619            }
620
621            fn into_reflect(self: Box<Self>) -> Box<dyn $crate::Reflect> {
622                self
623            }
624
625            fn as_reflect(&self) -> &dyn $crate::Reflect {
626                self
627            }
628
629            fn as_reflect_mut(&mut self) -> &mut dyn $crate::Reflect {
630                self
631            }
632
633            fn set(
634                &mut self,
635                value: Box<dyn $crate::Reflect>,
636            ) -> Result<(), Box<dyn $crate::Reflect>> {
637                *self = <dyn $crate::Reflect>::take(value)?;
638                Ok(())
639            }
640        }
641    };
642}
643
644pub(crate) use impl_full_reflect;