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