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