bevy_reflect/reflect.rs
1use crate::{
2 array_debug, enum_debug, list_debug, map_debug, serde::Serializable, struct_debug, tuple_debug,
3 tuple_struct_debug, Array, DynamicTypePath, Enum, List, Map, Struct, Tuple, TupleStruct,
4 TypeInfo, TypePath, Typed, ValueInfo,
5};
6use std::{
7 any::{Any, TypeId},
8 fmt::Debug,
9};
10
11use thiserror::Error;
12
13use crate::utility::NonGenericTypeInfoCell;
14
15macro_rules! impl_reflect_enum {
16 ($name:ident$(<$lifetime:lifetime>)?) => {
17 impl $name$(<$lifetime>)? {
18 /// Returns the "kind" of this reflected type without any information.
19 pub fn kind(&self) -> ReflectKind {
20 match self {
21 Self::Struct(_) => ReflectKind::Struct,
22 Self::TupleStruct(_) => ReflectKind::TupleStruct,
23 Self::Tuple(_) => ReflectKind::Tuple,
24 Self::List(_) => ReflectKind::List,
25 Self::Array(_) => ReflectKind::Array,
26 Self::Map(_) => ReflectKind::Map,
27 Self::Enum(_) => ReflectKind::Enum,
28 Self::Value(_) => ReflectKind::Value,
29 }
30 }
31 }
32
33 impl From<$name$(<$lifetime>)?> for ReflectKind {
34 fn from(value: $name) -> Self {
35 match value {
36 $name::Struct(_) => Self::Struct,
37 $name::TupleStruct(_) => Self::TupleStruct,
38 $name::Tuple(_) => Self::Tuple,
39 $name::List(_) => Self::List,
40 $name::Array(_) => Self::Array,
41 $name::Map(_) => Self::Map,
42 $name::Enum(_) => Self::Enum,
43 $name::Value(_) => Self::Value,
44 }
45 }
46 }
47 };
48}
49
50/// An immutable enumeration of "kinds" of a reflected type.
51///
52/// Each variant contains a trait object with methods specific to a kind of
53/// type.
54///
55/// A [`ReflectRef`] is obtained via [`Reflect::reflect_ref`].
56pub enum ReflectRef<'a> {
57 Struct(&'a dyn Struct),
58 TupleStruct(&'a dyn TupleStruct),
59 Tuple(&'a dyn Tuple),
60 List(&'a dyn List),
61 Array(&'a dyn Array),
62 Map(&'a dyn Map),
63 Enum(&'a dyn Enum),
64 Value(&'a dyn Reflect),
65}
66impl_reflect_enum!(ReflectRef<'_>);
67
68/// A mutable enumeration of "kinds" of a reflected type.
69///
70/// Each variant contains a trait object with methods specific to a kind of
71/// type.
72///
73/// A [`ReflectMut`] is obtained via [`Reflect::reflect_mut`].
74pub enum ReflectMut<'a> {
75 Struct(&'a mut dyn Struct),
76 TupleStruct(&'a mut dyn TupleStruct),
77 Tuple(&'a mut dyn Tuple),
78 List(&'a mut dyn List),
79 Array(&'a mut dyn Array),
80 Map(&'a mut dyn Map),
81 Enum(&'a mut dyn Enum),
82 Value(&'a mut dyn Reflect),
83}
84impl_reflect_enum!(ReflectMut<'_>);
85
86/// An owned enumeration of "kinds" of a reflected type.
87///
88/// Each variant contains a trait object with methods specific to a kind of
89/// type.
90///
91/// A [`ReflectOwned`] is obtained via [`Reflect::reflect_owned`].
92pub enum ReflectOwned {
93 Struct(Box<dyn Struct>),
94 TupleStruct(Box<dyn TupleStruct>),
95 Tuple(Box<dyn Tuple>),
96 List(Box<dyn List>),
97 Array(Box<dyn Array>),
98 Map(Box<dyn Map>),
99 Enum(Box<dyn Enum>),
100 Value(Box<dyn Reflect>),
101}
102impl_reflect_enum!(ReflectOwned);
103
104/// A enumeration of all error outcomes that might happen when running [`try_apply`](Reflect::try_apply).
105#[derive(Error, Debug)]
106pub enum ApplyError {
107 #[error("attempted to apply `{from_kind}` to `{to_kind}`")]
108 /// Attempted to apply the wrong [kind](ReflectKind) to a type, e.g. a struct to a enum.
109 MismatchedKinds {
110 from_kind: ReflectKind,
111 to_kind: ReflectKind,
112 },
113
114 #[error("enum variant `{variant_name}` doesn't have a field named `{field_name}`")]
115 /// Enum variant that we tried to apply to was missing a field.
116 MissingEnumField {
117 variant_name: Box<str>,
118 field_name: Box<str>,
119 },
120
121 #[error("`{from_type}` is not `{to_type}`")]
122 /// Tried to apply incompatible types.
123 MismatchedTypes {
124 from_type: Box<str>,
125 to_type: Box<str>,
126 },
127
128 #[error("attempted to apply type with {from_size} size to a type with {to_size} size")]
129 /// Attempted to apply to types with mismatched sizez, e.g. a [u8; 4] to [u8; 3].
130 DifferentSize { from_size: usize, to_size: usize },
131
132 #[error("variant with name `{variant_name}` does not exist on enum `{enum_name}`")]
133 /// The enum we tried to apply to didn't contain a variant with the give name.
134 UnknownVariant {
135 enum_name: Box<str>,
136 variant_name: Box<str>,
137 },
138}
139
140/// A zero-sized enumuration of the "kinds" of a reflected type.
141///
142/// A [`ReflectKind`] is obtained via [`Reflect::reflect_kind`],
143/// or via [`ReflectRef::kind`],[`ReflectMut::kind`] or [`ReflectOwned::kind`].
144#[derive(Debug, PartialEq, Eq, Clone, Copy)]
145pub enum ReflectKind {
146 Struct,
147 TupleStruct,
148 Tuple,
149 List,
150 Array,
151 Map,
152 Enum,
153 Value,
154}
155
156impl std::fmt::Display for ReflectKind {
157 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
158 match self {
159 ReflectKind::Struct => f.pad("struct"),
160 ReflectKind::TupleStruct => f.pad("tuple struct"),
161 ReflectKind::Tuple => f.pad("tuple"),
162 ReflectKind::List => f.pad("list"),
163 ReflectKind::Array => f.pad("array"),
164 ReflectKind::Map => f.pad("map"),
165 ReflectKind::Enum => f.pad("enum"),
166 ReflectKind::Value => f.pad("value"),
167 }
168 }
169}
170
171/// The core trait of [`bevy_reflect`], used for accessing and modifying data dynamically.
172///
173/// It's recommended to use the [derive macro] rather than manually implementing this trait.
174/// Doing so will automatically implement many other useful traits for reflection,
175/// including one of the appropriate subtraits: [`Struct`], [`TupleStruct`] or [`Enum`].
176///
177/// See the [crate-level documentation] to see how this trait and its subtraits can be used.
178///
179/// [`bevy_reflect`]: crate
180/// [derive macro]: bevy_reflect_derive::Reflect
181/// [crate-level documentation]: crate
182#[diagnostic::on_unimplemented(
183 message = "`{Self}` can not be reflected",
184 note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
185)]
186pub trait Reflect: DynamicTypePath + Any + Send + Sync {
187 /// Returns the [`TypeInfo`] of the type _represented_ by this value.
188 ///
189 /// For most types, this will simply return their own `TypeInfo`.
190 /// However, for dynamic types, such as [`DynamicStruct`] or [`DynamicList`],
191 /// this will return the type they represent
192 /// (or `None` if they don't represent any particular type).
193 ///
194 /// This method is great if you have an instance of a type or a `dyn Reflect`,
195 /// and want to access its [`TypeInfo`]. However, if this method is to be called
196 /// frequently, consider using [`TypeRegistry::get_type_info`] as it can be more
197 /// performant for such use cases.
198 ///
199 /// [`DynamicStruct`]: crate::DynamicStruct
200 /// [`DynamicList`]: crate::DynamicList
201 /// [`TypeRegistry::get_type_info`]: crate::TypeRegistry::get_type_info
202 fn get_represented_type_info(&self) -> Option<&'static TypeInfo>;
203
204 /// Returns the value as a [`Box<dyn Any>`][std::any::Any].
205 fn into_any(self: Box<Self>) -> Box<dyn Any>;
206
207 /// Returns the value as a [`&dyn Any`][std::any::Any].
208 fn as_any(&self) -> &dyn Any;
209
210 /// Returns the value as a [`&mut dyn Any`][std::any::Any].
211 fn as_any_mut(&mut self) -> &mut dyn Any;
212
213 /// Casts this type to a boxed reflected value.
214 fn into_reflect(self: Box<Self>) -> Box<dyn Reflect>;
215
216 /// Casts this type to a reflected value.
217 fn as_reflect(&self) -> &dyn Reflect;
218
219 /// Casts this type to a mutable reflected value.
220 fn as_reflect_mut(&mut self) -> &mut dyn Reflect;
221
222 /// Applies a reflected value to this value.
223 ///
224 /// If a type implements a subtrait of `Reflect`, then the semantics of this
225 /// method are as follows:
226 /// - If `T` is a [`Struct`], then the value of each named field of `value` is
227 /// applied to the corresponding named field of `self`. Fields which are
228 /// not present in both structs are ignored.
229 /// - If `T` is a [`TupleStruct`] or [`Tuple`], then the value of each
230 /// numbered field is applied to the corresponding numbered field of
231 /// `self.` Fields which are not present in both values are ignored.
232 /// - If `T` is an [`Enum`], then the variant of `self` is `updated` to match
233 /// the variant of `value`. The corresponding fields of that variant are
234 /// applied from `value` onto `self`. Fields which are not present in both
235 /// values are ignored.
236 /// - If `T` is a [`List`] or [`Array`], then each element of `value` is applied
237 /// to the corresponding element of `self`. Up to `self.len()` items are applied,
238 /// and excess elements in `value` are appended to `self`.
239 /// - If `T` is a [`Map`], then for each key in `value`, the associated
240 /// value is applied to the value associated with the same key in `self`.
241 /// Keys which are not present in `self` are inserted.
242 /// - If `T` is none of these, then `value` is downcast to `T`, cloned, and
243 /// assigned to `self`.
244 ///
245 /// Note that `Reflect` must be implemented manually for [`List`]s and
246 /// [`Map`]s in order to achieve the correct semantics, as derived
247 /// implementations will have the semantics for [`Struct`], [`TupleStruct`], [`Enum`]
248 /// or none of the above depending on the kind of type. For lists and maps, use the
249 /// [`list_apply`] and [`map_apply`] helper functions when implementing this method.
250 ///
251 /// [`list_apply`]: crate::list_apply
252 /// [`map_apply`]: crate::map_apply
253 ///
254 /// # Panics
255 ///
256 /// Derived implementations of this method will panic:
257 /// - If the type of `value` is not of the same kind as `T` (e.g. if `T` is
258 /// a `List`, while `value` is a `Struct`).
259 /// - If `T` is any complex type and the corresponding fields or elements of
260 /// `self` and `value` are not of the same type.
261 /// - If `T` is a value type and `self` cannot be downcast to `T`
262 fn apply(&mut self, value: &dyn Reflect) {
263 Reflect::try_apply(self, value).unwrap();
264 }
265
266 /// Tries to [`apply`](Reflect::apply) a reflected value to this value.
267 ///
268 /// Functions the same as the [`apply`](Reflect::apply) function but returns an error instead of
269 /// panicking.
270 ///
271 /// # Handling Errors
272 ///
273 /// This function may leave `self` in a partially mutated state if a error was encountered on the way.
274 /// consider maintaining a cloned instance of this data you can switch to if a error is encountered.
275 fn try_apply(&mut self, value: &dyn Reflect) -> Result<(), ApplyError>;
276
277 /// Performs a type-checked assignment of a reflected value to this value.
278 ///
279 /// If `value` does not contain a value of type `T`, returns an `Err`
280 /// containing the trait object.
281 fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>;
282
283 /// Returns a zero-sized enumeration of "kinds" of type.
284 ///
285 /// See [`ReflectKind`].
286 fn reflect_kind(&self) -> ReflectKind {
287 self.reflect_ref().kind()
288 }
289
290 /// Returns an immutable enumeration of "kinds" of type.
291 ///
292 /// See [`ReflectRef`].
293 fn reflect_ref(&self) -> ReflectRef;
294
295 /// Returns a mutable enumeration of "kinds" of type.
296 ///
297 /// See [`ReflectMut`].
298 fn reflect_mut(&mut self) -> ReflectMut;
299
300 /// Returns an owned enumeration of "kinds" of type.
301 ///
302 /// See [`ReflectOwned`].
303 fn reflect_owned(self: Box<Self>) -> ReflectOwned;
304
305 /// Clones the value as a `Reflect` trait object.
306 ///
307 /// When deriving `Reflect` for a struct, tuple struct or enum, the value is
308 /// cloned via [`Struct::clone_dynamic`], [`TupleStruct::clone_dynamic`],
309 /// or [`Enum::clone_dynamic`], respectively.
310 /// Implementors of other `Reflect` subtraits (e.g. [`List`], [`Map`]) should
311 /// use those subtraits' respective `clone_dynamic` methods.
312 fn clone_value(&self) -> Box<dyn Reflect>;
313
314 /// Returns a hash of the value (which includes the type).
315 ///
316 /// If the underlying type does not support hashing, returns `None`.
317 fn reflect_hash(&self) -> Option<u64> {
318 None
319 }
320
321 /// Returns a "partial equality" comparison result.
322 ///
323 /// If the underlying type does not support equality testing, returns `None`.
324 fn reflect_partial_eq(&self, _value: &dyn Reflect) -> Option<bool> {
325 None
326 }
327
328 /// Debug formatter for the value.
329 ///
330 /// Any value that is not an implementor of other `Reflect` subtraits
331 /// (e.g. [`List`], [`Map`]), will default to the format: `"Reflect(type_path)"`,
332 /// where `type_path` is the [type path] of the underlying type.
333 ///
334 /// [type path]: TypePath::type_path
335 fn debug(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
336 match self.reflect_ref() {
337 ReflectRef::Struct(dyn_struct) => struct_debug(dyn_struct, f),
338 ReflectRef::TupleStruct(dyn_tuple_struct) => tuple_struct_debug(dyn_tuple_struct, f),
339 ReflectRef::Tuple(dyn_tuple) => tuple_debug(dyn_tuple, f),
340 ReflectRef::List(dyn_list) => list_debug(dyn_list, f),
341 ReflectRef::Array(dyn_array) => array_debug(dyn_array, f),
342 ReflectRef::Map(dyn_map) => map_debug(dyn_map, f),
343 ReflectRef::Enum(dyn_enum) => enum_debug(dyn_enum, f),
344 _ => write!(f, "Reflect({})", self.reflect_type_path()),
345 }
346 }
347
348 /// Returns a serializable version of the value.
349 ///
350 /// If the underlying type does not support serialization, returns `None`.
351 fn serializable(&self) -> Option<Serializable> {
352 None
353 }
354
355 /// Indicates whether or not this type is a _dynamic_ type.
356 ///
357 /// Dynamic types include the ones built-in to this [crate],
358 /// such as [`DynamicStruct`], [`DynamicList`], and [`DynamicTuple`].
359 /// However, they may be custom types used as proxies for other types
360 /// or to facilitate scripting capabilities.
361 ///
362 /// By default, this method will return `false`.
363 ///
364 /// [`DynamicStruct`]: crate::DynamicStruct
365 /// [`DynamicList`]: crate::DynamicList
366 /// [`DynamicTuple`]: crate::DynamicTuple
367 fn is_dynamic(&self) -> bool {
368 false
369 }
370}
371
372impl Debug for dyn Reflect {
373 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
374 self.debug(f)
375 }
376}
377
378impl Typed for dyn Reflect {
379 fn type_info() -> &'static TypeInfo {
380 static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
381 CELL.get_or_set(|| TypeInfo::Value(ValueInfo::new::<Self>()))
382 }
383}
384
385// The following implementation never actually shadows the concrete TypePath implementation.
386
387// See this playground (https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=589064053f27bc100d90da89c6a860aa).
388impl TypePath for dyn Reflect {
389 fn type_path() -> &'static str {
390 "dyn bevy_reflect::Reflect"
391 }
392
393 fn short_type_path() -> &'static str {
394 "dyn Reflect"
395 }
396}
397
398#[deny(rustdoc::broken_intra_doc_links)]
399impl dyn Reflect {
400 /// Downcasts the value to type `T`, consuming the trait object.
401 ///
402 /// If the underlying value is not of type `T`, returns `Err(self)`.
403 pub fn downcast<T: Reflect>(self: Box<dyn Reflect>) -> Result<Box<T>, Box<dyn Reflect>> {
404 if self.is::<T>() {
405 Ok(self.into_any().downcast().unwrap())
406 } else {
407 Err(self)
408 }
409 }
410
411 /// Downcasts the value to type `T`, unboxing and consuming the trait object.
412 ///
413 /// If the underlying value is not of type `T`, returns `Err(self)`.
414 pub fn take<T: Reflect>(self: Box<dyn Reflect>) -> Result<T, Box<dyn Reflect>> {
415 self.downcast::<T>().map(|value| *value)
416 }
417
418 /// Returns `true` if the underlying value represents a value of type `T`, or `false`
419 /// otherwise.
420 ///
421 /// Read `is` for more information on underlying values and represented types.
422 #[inline]
423 pub fn represents<T: Reflect + TypePath>(&self) -> bool {
424 self.get_represented_type_info()
425 .map(|t| t.type_path() == T::type_path())
426 .unwrap_or(false)
427 }
428
429 /// Returns `true` if the underlying value is of type `T`, or `false`
430 /// otherwise.
431 ///
432 /// The underlying value is the concrete type that is stored in this `dyn` object;
433 /// it can be downcasted to. In the case that this underlying value "represents"
434 /// a different type, like the Dynamic\*\*\* types do, you can call `represents`
435 /// to determine what type they represent. Represented types cannot be downcasted
436 /// to, but you can use [`FromReflect`] to create a value of the represented type from them.
437 ///
438 /// [`FromReflect`]: crate::FromReflect
439 #[inline]
440 pub fn is<T: Reflect>(&self) -> bool {
441 self.type_id() == TypeId::of::<T>()
442 }
443
444 /// Downcasts the value to type `T` by reference.
445 ///
446 /// If the underlying value is not of type `T`, returns `None`.
447 #[inline]
448 pub fn downcast_ref<T: Reflect>(&self) -> Option<&T> {
449 self.as_any().downcast_ref::<T>()
450 }
451
452 /// Downcasts the value to type `T` by mutable reference.
453 ///
454 /// If the underlying value is not of type `T`, returns `None`.
455 #[inline]
456 pub fn downcast_mut<T: Reflect>(&mut self) -> Option<&mut T> {
457 self.as_any_mut().downcast_mut::<T>()
458 }
459}