Skip to main content

bevy_reflect/
reflect.rs

1use crate::{
2    array::array_debug, enums::enum_debug, list::list_debug, map::map_debug, set::set_debug,
3    structs::struct_debug, tuple::tuple_debug, tuple_struct::tuple_struct_debug, DynamicTypePath,
4    DynamicTyped, OpaqueInfo, ReflectCloneError, ReflectKind, ReflectKindMismatchError, ReflectMut,
5    ReflectOwned, ReflectRef, TypeInfo, TypePath, Typed,
6};
7use alloc::borrow::Cow;
8use alloc::boxed::Box;
9use alloc::string::ToString;
10use core::{
11    any::{Any, TypeId},
12    cmp::Ordering,
13    fmt::Debug,
14};
15
16use thiserror::Error;
17
18use crate::utility::NonGenericTypeInfoCell;
19
20/// A enumeration of all error outcomes that might happen when running [`try_apply`](PartialReflect::try_apply).
21#[derive(#[allow(unused_qualifications)]
#[automatically_derived]
impl ::core::fmt::Display for ApplyError {
    fn fmt(&self, __formatter: &mut ::core::fmt::Formatter)
        -> ::core::fmt::Result {
        use ::thiserror::__private18::AsDisplay as _;

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