diff --git a/crates/bevy_asset/src/path.rs b/crates/bevy_asset/src/path.rs index 77039880fb9ce..6ec1e8eaa6b78 100644 --- a/crates/bevy_asset/src/path.rs +++ b/crates/bevy_asset/src/path.rs @@ -2,8 +2,8 @@ use crate::io::AssetSourceId; use bevy_reflect::{ std_traits::ReflectDefault, utility::NonGenericTypeInfoCell, FromReflect, FromType, GetTypeRegistration, Reflect, ReflectDeserialize, ReflectFromPtr, ReflectFromReflect, - ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, TypeInfo, TypePath, TypeRegistration, - Typed, ValueInfo, + ReflectKind, ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, TypeInfo, TypePath, + TypeRegistration, Typed, ValueInfo, }; use bevy_utils::CowArc; use serde::{de::Visitor, Deserialize, Serialize}; @@ -681,6 +681,9 @@ impl Reflect for AssetPath<'static> { *self = ::take(value)?; Ok(()) } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Value + } fn reflect_ref(&self) -> ReflectRef { ReflectRef::Value(self) } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs index b9cd484267e5d..801470e49e3f4 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs @@ -264,6 +264,10 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> proc_macro2::TokenStream } } + fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind { + #bevy_reflect_path::ReflectKind::Enum + } + fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef { #bevy_reflect_path::ReflectRef::Enum(self) } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs index 90c51f36232db..d32048a5f934d 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs @@ -219,6 +219,10 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> proc_macro2::TokenS } } + fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind { + #bevy_reflect_path::ReflectKind::Struct + } + fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef { #bevy_reflect_path::ReflectRef::Struct(self) } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs index b8a17100d04bc..cca38ecab30e6 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs @@ -187,6 +187,10 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> proc_macro2:: } } + fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind { + #bevy_reflect_path::ReflectKind::TupleStruct + } + fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef { #bevy_reflect_path::ReflectRef::TupleStruct(self) } diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs index 96725cf88253f..84dd4ae9e3375 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs @@ -101,6 +101,10 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> proc_macro2::TokenStream { #FQResult::Ok(()) } + fn reflect_kind(&self) -> #bevy_reflect_path::ReflectKind { + #bevy_reflect_path::ReflectKind::Value + } + fn reflect_ref(&self) -> #bevy_reflect_path::ReflectRef { #bevy_reflect_path::ReflectRef::Value(self) } diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index 82e6fb53d92f2..0b704a21f77e9 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -1,6 +1,6 @@ use crate::{ - self as bevy_reflect, utility::reflect_hasher, Reflect, ReflectMut, ReflectOwned, ReflectRef, - TypeInfo, TypePath, TypePathTable, + self as bevy_reflect, utility::reflect_hasher, Reflect, ReflectKind, ReflectMut, ReflectOwned, + ReflectRef, TypeInfo, TypePath, TypePathTable, }; use bevy_reflect_derive::impl_type_path; use std::{ @@ -268,6 +268,11 @@ impl Reflect for DynamicArray { Ok(()) } + #[inline] + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Array + } + #[inline] fn reflect_ref(&self) -> ReflectRef { ReflectRef::Array(self) diff --git a/crates/bevy_reflect/src/enums/dynamic_enum.rs b/crates/bevy_reflect/src/enums/dynamic_enum.rs index 2895d3c9a8522..d01c351448ae0 100644 --- a/crates/bevy_reflect/src/enums/dynamic_enum.rs +++ b/crates/bevy_reflect/src/enums/dynamic_enum.rs @@ -2,8 +2,8 @@ use bevy_reflect_derive::impl_type_path; use crate::{ self as bevy_reflect, enum_debug, enum_hash, enum_partial_eq, DynamicStruct, DynamicTuple, - Enum, Reflect, ReflectMut, ReflectOwned, ReflectRef, Struct, Tuple, TypeInfo, VariantFieldIter, - VariantType, + Enum, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Struct, Tuple, TypeInfo, + VariantFieldIter, VariantType, }; use std::any::Any; use std::fmt::Formatter; @@ -379,6 +379,11 @@ impl Reflect for DynamicEnum { Ok(()) } + #[inline] + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Enum + } + #[inline] fn reflect_ref(&self) -> ReflectRef { ReflectRef::Enum(self) diff --git a/crates/bevy_reflect/src/impls/smallvec.rs b/crates/bevy_reflect/src/impls/smallvec.rs index 491404a3df11a..a911b3b2fdc0e 100644 --- a/crates/bevy_reflect/src/impls/smallvec.rs +++ b/crates/bevy_reflect/src/impls/smallvec.rs @@ -7,7 +7,7 @@ use std::any::Any; use crate::utility::GenericTypeInfoCell; use crate::{ self as bevy_reflect, FromReflect, FromType, GetTypeRegistration, List, ListInfo, ListIter, - Reflect, ReflectFromPtr, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, + Reflect, ReflectFromPtr, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, TypeRegistration, Typed, }; @@ -119,6 +119,10 @@ where Ok(()) } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::List + } + fn reflect_ref(&self) -> ReflectRef { ReflectRef::List(self) } diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 61ae6db26bc77..4a1b26ac4ea56 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -3,8 +3,8 @@ use crate::{self as bevy_reflect, ReflectFromPtr, ReflectFromReflect, ReflectOwn use crate::{ impl_type_path, map_apply, map_partial_eq, Array, ArrayInfo, ArrayIter, DynamicEnum, DynamicMap, Enum, EnumInfo, FromReflect, FromType, GetTypeRegistration, List, ListInfo, - ListIter, Map, MapInfo, MapIter, Reflect, ReflectDeserialize, ReflectMut, ReflectRef, - ReflectSerialize, TupleVariantInfo, TypeInfo, TypePath, TypeRegistration, Typed, + ListIter, Map, MapInfo, MapIter, Reflect, ReflectDeserialize, ReflectKind, ReflectMut, + ReflectRef, ReflectSerialize, TupleVariantInfo, TypeInfo, TypePath, TypeRegistration, Typed, UnitVariantInfo, UnnamedField, ValueInfo, VariantFieldIter, VariantInfo, VariantType, }; @@ -317,6 +317,10 @@ macro_rules! impl_reflect_for_veclike { Ok(()) } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::List + } + fn reflect_ref(&self) -> ReflectRef { ReflectRef::List(self) } @@ -535,6 +539,10 @@ macro_rules! impl_reflect_for_hashmap { Ok(()) } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Map + } + fn reflect_ref(&self) -> ReflectRef { ReflectRef::Map(self) } @@ -687,6 +695,11 @@ impl Reflect for [T; N] { Ok(()) } + #[inline] + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Array + } + #[inline] fn reflect_ref(&self) -> ReflectRef { ReflectRef::Array(self) @@ -935,6 +948,10 @@ impl Reflect for Option { Ok(()) } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Enum + } + fn reflect_ref(&self) -> ReflectRef { ReflectRef::Enum(self) } @@ -1080,6 +1097,10 @@ impl Reflect for Cow<'static, str> { Ok(()) } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Value + } + fn reflect_ref(&self) -> ReflectRef { ReflectRef::Value(self) } @@ -1257,6 +1278,10 @@ impl Reflect for Cow<'static, [T]> { Ok(()) } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::List + } + fn reflect_ref(&self) -> ReflectRef { ReflectRef::List(self) } @@ -1454,6 +1479,10 @@ impl Reflect for &'static Path { Ok(()) } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Value + } + fn reflect_ref(&self) -> ReflectRef { ReflectRef::Value(self) } @@ -1551,6 +1580,10 @@ impl Reflect for Cow<'static, Path> { Ok(()) } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Value + } + fn reflect_ref(&self) -> ReflectRef { ReflectRef::Value(self) } diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 15d61b1bba2a8..b11bbbf6ac1ab 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -93,8 +93,8 @@ //! Since most data is passed around as `dyn Reflect`, //! the `Reflect` trait has methods for going to and from these subtraits. //! -//! [`Reflect::reflect_ref`], [`Reflect::reflect_mut`], and [`Reflect::reflect_owned`] all return -//! an enum that respectively contains immutable, mutable, and owned access to the type as a subtrait object. +//! [`Reflect::reflect_kind`], [`Reflect::reflect_ref`], [`Reflect::reflect_mut`], and [`Reflect::reflect_owned`] all return +//! an enum that respectively contains zero-sized, immutable, mutable, and owned access to the type as a subtrait object. //! //! For example, we can get out a `dyn Tuple` from our reflected tuple type using one of these methods. //! diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index 8c0f03837c470..bc423132c02ea 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -6,8 +6,8 @@ use bevy_reflect_derive::impl_type_path; use crate::utility::reflect_hasher; use crate::{ - self as bevy_reflect, FromReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, - TypePath, TypePathTable, + self as bevy_reflect, FromReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, + TypeInfo, TypePath, TypePathTable, }; /// A trait used to power [list-like] operations via [reflection]. @@ -318,6 +318,11 @@ impl Reflect for DynamicList { Ok(()) } + #[inline] + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::List + } + #[inline] fn reflect_ref(&self) -> ReflectRef { ReflectRef::List(self) diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index 34e41bf5ddb6a..5bfb68783788d 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -6,8 +6,8 @@ use bevy_reflect_derive::impl_type_path; use bevy_utils::{Entry, HashMap}; use crate::{ - self as bevy_reflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, - TypePathTable, + self as bevy_reflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, + TypePath, TypePathTable, }; /// A trait used to power [map-like] operations via [reflection]. @@ -354,6 +354,10 @@ impl Reflect for DynamicMap { Ok(()) } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Map + } + fn reflect_ref(&self) -> ReflectRef { ReflectRef::Map(self) } diff --git a/crates/bevy_reflect/src/path/access.rs b/crates/bevy_reflect/src/path/access.rs index ee697f8468c4c..5bb4b5b099261 100644 --- a/crates/bevy_reflect/src/path/access.rs +++ b/crates/bevy_reflect/src/path/access.rs @@ -2,8 +2,8 @@ use std::{borrow::Cow, fmt}; -use super::error::{AccessErrorKind, TypeKind}; -use crate::{AccessError, Reflect, ReflectMut, ReflectRef, VariantType}; +use super::error::AccessErrorKind; +use crate::{AccessError, Reflect, ReflectKind, ReflectMut, ReflectRef, VariantType}; type InnerResult = Result; @@ -55,7 +55,7 @@ impl<'a> Access<'a> { offset: Option, ) -> Result<&'r dyn Reflect, AccessError<'a>> { self.element_inner(base) - .and_then(|opt| opt.ok_or(AccessErrorKind::MissingField(base.into()))) + .and_then(|opt| opt.ok_or(AccessErrorKind::MissingField(base.reflect_kind()))) .map_err(|err| err.with_access(self.clone(), offset)) } @@ -78,7 +78,7 @@ impl<'a> Access<'a> { }, (Self::Field(_) | Self::FieldIndex(_), actual) => { Err(AccessErrorKind::IncompatibleTypes { - expected: TypeKind::Struct, + expected: ReflectKind::Struct, actual: actual.into(), }) } @@ -90,14 +90,14 @@ impl<'a> Access<'a> { actual => Err(invalid_variant(VariantType::Tuple, actual)), }, (Self::TupleIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes { - expected: TypeKind::Tuple, + expected: ReflectKind::Tuple, actual: actual.into(), }), (&Self::ListIndex(index), List(list)) => Ok(list.get(index)), (&Self::ListIndex(index), Array(list)) => Ok(list.get(index)), (Self::ListIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes { - expected: TypeKind::List, + expected: ReflectKind::List, actual: actual.into(), }), } @@ -108,7 +108,7 @@ impl<'a> Access<'a> { base: &'r mut dyn Reflect, offset: Option, ) -> Result<&'r mut dyn Reflect, AccessError<'a>> { - let kind = base.into(); + let kind = base.reflect_kind(); self.element_inner_mut(base) .and_then(|maybe| maybe.ok_or(AccessErrorKind::MissingField(kind))) @@ -137,7 +137,7 @@ impl<'a> Access<'a> { }, (Self::Field(_) | Self::FieldIndex(_), actual) => { Err(AccessErrorKind::IncompatibleTypes { - expected: TypeKind::Struct, + expected: ReflectKind::Struct, actual: actual.into(), }) } @@ -149,14 +149,14 @@ impl<'a> Access<'a> { actual => Err(invalid_variant(VariantType::Tuple, actual)), }, (Self::TupleIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes { - expected: TypeKind::Tuple, + expected: ReflectKind::Tuple, actual: actual.into(), }), (&Self::ListIndex(index), List(list)) => Ok(list.get_mut(index)), (&Self::ListIndex(index), Array(list)) => Ok(list.get_mut(index)), (Self::ListIndex(_), actual) => Err(AccessErrorKind::IncompatibleTypes { - expected: TypeKind::List, + expected: ReflectKind::List, actual: actual.into(), }), } diff --git a/crates/bevy_reflect/src/path/error.rs b/crates/bevy_reflect/src/path/error.rs index b35d953e9763d..6716485ba7dc6 100644 --- a/crates/bevy_reflect/src/path/error.rs +++ b/crates/bevy_reflect/src/path/error.rs @@ -1,22 +1,22 @@ use std::fmt; use super::Access; -use crate::{Reflect, ReflectMut, ReflectRef, VariantType}; +use crate::{ReflectKind, VariantType}; /// The kind of [`AccessError`], along with some kind-specific information. #[derive(Debug, PartialEq, Eq, Clone)] pub enum AccessErrorKind { /// An error that occurs when a certain type doesn't /// contain the value referenced by the [`Access`]. - MissingField(TypeKind), + MissingField(ReflectKind), /// An error that occurs when using an [`Access`] on the wrong type. /// (i.e. a [`ListIndex`](Access::ListIndex) on a struct, or a [`TupleIndex`](Access::TupleIndex) on a list) IncompatibleTypes { - /// The [`TypeKind`] that was expected based on the [`Access`]. - expected: TypeKind, - /// The actual [`TypeKind`] that was found. - actual: TypeKind, + /// The [`ReflectKind`] that was expected based on the [`Access`]. + expected: ReflectKind, + /// The actual [`ReflectKind`] that was found. + actual: ReflectKind, }, /// An error that occurs when using an [`Access`] on the wrong enum variant. @@ -127,81 +127,3 @@ impl std::fmt::Display for AccessError<'_> { } } impl std::error::Error for AccessError<'_> {} - -/// The kind of the type trying to be accessed. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[allow(missing_docs /* Variants are self-explanatory */)] -pub enum TypeKind { - Struct, - TupleStruct, - Tuple, - List, - Array, - Map, - Enum, - Value, - Unit, -} - -impl fmt::Display for TypeKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - TypeKind::Struct => f.pad("struct"), - TypeKind::TupleStruct => f.pad("tuple struct"), - TypeKind::Tuple => f.pad("tuple"), - TypeKind::List => f.pad("list"), - TypeKind::Array => f.pad("array"), - TypeKind::Map => f.pad("map"), - TypeKind::Enum => f.pad("enum"), - TypeKind::Value => f.pad("value"), - TypeKind::Unit => f.pad("unit"), - } - } -} -impl From> for TypeKind { - fn from(value: ReflectRef) -> Self { - match value { - ReflectRef::Struct(_) => TypeKind::Struct, - ReflectRef::TupleStruct(_) => TypeKind::TupleStruct, - ReflectRef::Tuple(_) => TypeKind::Tuple, - ReflectRef::List(_) => TypeKind::List, - ReflectRef::Array(_) => TypeKind::Array, - ReflectRef::Map(_) => TypeKind::Map, - ReflectRef::Enum(_) => TypeKind::Enum, - ReflectRef::Value(_) => TypeKind::Value, - } - } -} -impl From<&dyn Reflect> for TypeKind { - fn from(value: &dyn Reflect) -> Self { - value.reflect_ref().into() - } -} -impl From> for TypeKind { - fn from(value: ReflectMut) -> Self { - match value { - ReflectMut::Struct(_) => TypeKind::Struct, - ReflectMut::TupleStruct(_) => TypeKind::TupleStruct, - ReflectMut::Tuple(_) => TypeKind::Tuple, - ReflectMut::List(_) => TypeKind::List, - ReflectMut::Array(_) => TypeKind::Array, - ReflectMut::Map(_) => TypeKind::Map, - ReflectMut::Enum(_) => TypeKind::Enum, - ReflectMut::Value(_) => TypeKind::Value, - } - } -} -impl From<&mut dyn Reflect> for TypeKind { - fn from(value: &mut dyn Reflect) -> Self { - value.reflect_ref().into() - } -} -impl From for TypeKind { - fn from(value: VariantType) -> Self { - match value { - VariantType::Struct => TypeKind::Struct, - VariantType::Tuple => TypeKind::Tuple, - VariantType::Unit => TypeKind::Unit, - } - } -} diff --git a/crates/bevy_reflect/src/path/mod.rs b/crates/bevy_reflect/src/path/mod.rs index ce22d86e5c32f..6fbb88998647d 100644 --- a/crates/bevy_reflect/src/path/mod.rs +++ b/crates/bevy_reflect/src/path/mod.rs @@ -491,7 +491,7 @@ mod tests { use super::*; use crate as bevy_reflect; use crate::*; - use error::{AccessErrorKind, TypeKind}; + use error::AccessErrorKind; #[derive(Reflect)] struct A { @@ -562,8 +562,8 @@ mod tests { fn invalid_access( offset: usize, - actual: TypeKind, - expected: TypeKind, + actual: ReflectKind, + expected: ReflectKind, access: &'static str, ) -> StaticError { ReflectPathError::InvalidAccess(AccessError { @@ -733,7 +733,7 @@ mod tests { assert_eq!( a.reflect_path("x.notreal").err().unwrap(), ReflectPathError::InvalidAccess(AccessError { - kind: AccessErrorKind::MissingField(TypeKind::Struct), + kind: AccessErrorKind::MissingField(ReflectKind::Struct), access: access_field("notreal"), offset: Some(2), }) @@ -754,11 +754,11 @@ mod tests { ); assert_eq!( a.reflect_path("x[0]").err().unwrap(), - invalid_access(2, TypeKind::Struct, TypeKind::List, "x[0]") + invalid_access(2, ReflectKind::Struct, ReflectKind::List, "x[0]") ); assert_eq!( a.reflect_path("y.x").err().unwrap(), - invalid_access(2, TypeKind::List, TypeKind::Struct, "y.x") + invalid_access(2, ReflectKind::List, ReflectKind::Struct, "y.x") ); } diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index 458022566baa5..9a50decb7240b 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -10,12 +10,47 @@ use std::{ use crate::utility::NonGenericTypeInfoCell; -/// An immutable enumeration of "kinds" of reflected type. +macro_rules! impl_reflect_enum { + ($name:ident$(<$lifetime:lifetime>)?) => { + impl $name$(<$lifetime>)? { + /// Returns the "kind" of this reflected type without any information. + pub fn kind(&self) -> ReflectKind { + match self { + Self::Struct(_) => ReflectKind::Struct, + Self::TupleStruct(_) => ReflectKind::TupleStruct, + Self::Tuple(_) => ReflectKind::Tuple, + Self::List(_) => ReflectKind::List, + Self::Array(_) => ReflectKind::Array, + Self::Map(_) => ReflectKind::Map, + Self::Enum(_) => ReflectKind::Enum, + Self::Value(_) => ReflectKind::Value, + } + } + } + + impl From<$name$(<$lifetime>)?> for ReflectKind { + fn from(value: $name) -> Self { + match value { + $name::Struct(_) => Self::Struct, + $name::TupleStruct(_) => Self::TupleStruct, + $name::Tuple(_) => Self::Tuple, + $name::List(_) => Self::List, + $name::Array(_) => Self::Array, + $name::Map(_) => Self::Map, + $name::Enum(_) => Self::Enum, + $name::Value(_) => Self::Value, + } + } + } + }; +} + +/// An immutable enumeration of "kinds" of a reflected type. /// /// Each variant contains a trait object with methods specific to a kind of /// type. /// -/// A `ReflectRef` is obtained via [`Reflect::reflect_ref`]. +/// A [`ReflectRef`] is obtained via [`Reflect::reflect_ref`]. pub enum ReflectRef<'a> { Struct(&'a dyn Struct), TupleStruct(&'a dyn TupleStruct), @@ -26,13 +61,14 @@ pub enum ReflectRef<'a> { Enum(&'a dyn Enum), Value(&'a dyn Reflect), } +impl_reflect_enum!(ReflectRef<'_>); -/// A mutable enumeration of "kinds" of reflected type. +/// A mutable enumeration of "kinds" of a reflected type. /// /// Each variant contains a trait object with methods specific to a kind of /// type. /// -/// A `ReflectMut` is obtained via [`Reflect::reflect_mut`]. +/// A [`ReflectMut`] is obtained via [`Reflect::reflect_mut`]. pub enum ReflectMut<'a> { Struct(&'a mut dyn Struct), TupleStruct(&'a mut dyn TupleStruct), @@ -43,13 +79,14 @@ pub enum ReflectMut<'a> { Enum(&'a mut dyn Enum), Value(&'a mut dyn Reflect), } +impl_reflect_enum!(ReflectMut<'_>); -/// An owned enumeration of "kinds" of reflected type. +/// An owned enumeration of "kinds" of a reflected type. /// /// Each variant contains a trait object with methods specific to a kind of /// type. /// -/// A `ReflectOwned` is obtained via [`Reflect::reflect_owned`]. +/// A [`ReflectOwned`] is obtained via [`Reflect::reflect_owned`]. pub enum ReflectOwned { Struct(Box), TupleStruct(Box), @@ -60,6 +97,38 @@ pub enum ReflectOwned { Enum(Box), Value(Box), } +impl_reflect_enum!(ReflectOwned); + +/// A zero-sized enumuration of the "kinds" of a reflected type. +/// +/// A [`ReflectKind`] is obtained via [`Reflect::reflect_kind`], +/// or via [`ReflectRef::kind`],[`ReflectMut::kind`] or [`ReflectOwned::kind`]. +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub enum ReflectKind { + Struct, + TupleStruct, + Tuple, + List, + Array, + Map, + Enum, + Value, +} + +impl std::fmt::Display for ReflectKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ReflectKind::Struct => f.pad("struct"), + ReflectKind::TupleStruct => f.pad("tuple struct"), + ReflectKind::Tuple => f.pad("tuple"), + ReflectKind::List => f.pad("list"), + ReflectKind::Array => f.pad("array"), + ReflectKind::Map => f.pad("map"), + ReflectKind::Enum => f.pad("enum"), + ReflectKind::Value => f.pad("value"), + } + } +} /// The core trait of [`bevy_reflect`], used for accessing and modifying data dynamically. /// @@ -156,7 +225,14 @@ pub trait Reflect: DynamicTypePath + Any + Send + Sync { /// containing the trait object. fn set(&mut self, value: Box) -> Result<(), Box>; - /// Returns an enumeration of "kinds" of type. + /// Returns a zero-sized enumeration of "kinds" of type. + /// + /// See [`ReflectKind`]. + fn reflect_kind(&self) -> ReflectKind { + self.reflect_ref().kind() + } + + /// Returns an immutable enumeration of "kinds" of type. /// /// See [`ReflectRef`]. fn reflect_ref(&self) -> ReflectRef; diff --git a/crates/bevy_reflect/src/struct_trait.rs b/crates/bevy_reflect/src/struct_trait.rs index dd118d25a9b4a..d26ea6adb5f42 100644 --- a/crates/bevy_reflect/src/struct_trait.rs +++ b/crates/bevy_reflect/src/struct_trait.rs @@ -1,6 +1,6 @@ use crate::{ - self as bevy_reflect, NamedField, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, - TypePath, TypePathTable, + self as bevy_reflect, NamedField, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, + TypeInfo, TypePath, TypePathTable, }; use bevy_reflect_derive::impl_type_path; use bevy_utils::HashMap; @@ -438,6 +438,11 @@ impl Reflect for DynamicStruct { Ok(()) } + #[inline] + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Struct + } + #[inline] fn reflect_ref(&self) -> ReflectRef { ReflectRef::Struct(self) diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index bbd973c2f28ef..78d78e1a42ea2 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -1,12 +1,12 @@ use bevy_reflect_derive::impl_type_path; use bevy_utils::all_tuples; -use crate::TypePathTable; use crate::{ self as bevy_reflect, utility::GenericTypePathCell, FromReflect, GetTypeRegistration, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, TypeRegistration, Typed, UnnamedField, }; +use crate::{ReflectKind, TypePathTable}; use std::any::{Any, TypeId}; use std::fmt::{Debug, Formatter}; use std::slice::Iter; @@ -344,6 +344,11 @@ impl Reflect for DynamicTuple { Ok(()) } + #[inline] + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Tuple + } + #[inline] fn reflect_ref(&self) -> ReflectRef { ReflectRef::Tuple(self) @@ -545,6 +550,10 @@ macro_rules! impl_reflect_tuple { Ok(()) } + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::Tuple + } + fn reflect_ref(&self) -> ReflectRef { ReflectRef::Tuple(self) } diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index 8e3a13d97128a..c8699b506e040 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -1,8 +1,8 @@ use bevy_reflect_derive::impl_type_path; use crate::{ - self as bevy_reflect, DynamicTuple, Reflect, ReflectMut, ReflectOwned, ReflectRef, Tuple, - TypeInfo, TypePath, TypePathTable, UnnamedField, + self as bevy_reflect, DynamicTuple, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, + Tuple, TypeInfo, TypePath, TypePathTable, UnnamedField, }; use std::any::{Any, TypeId}; use std::fmt::{Debug, Formatter}; @@ -346,6 +346,11 @@ impl Reflect for DynamicTupleStruct { Ok(()) } + #[inline] + fn reflect_kind(&self) -> ReflectKind { + ReflectKind::TupleStruct + } + #[inline] fn reflect_ref(&self) -> ReflectRef { ReflectRef::TupleStruct(self) diff --git a/crates/bevy_render/src/render_asset.rs b/crates/bevy_render/src/render_asset.rs index 6473196ecc05f..3eb0d2f0b610e 100644 --- a/crates/bevy_render/src/render_asset.rs +++ b/crates/bevy_render/src/render_asset.rs @@ -9,8 +9,8 @@ use bevy_ecs::{ }; use bevy_reflect::{ utility::{reflect_hasher, NonGenericTypeInfoCell}, - FromReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, Typed, - ValueInfo, + FromReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, + Typed, ValueInfo, }; use bevy_utils::{thiserror::Error, HashMap, HashSet}; use serde::{Deserialize, Serialize}; @@ -122,6 +122,9 @@ impl Reflect for RenderAssetUsages { *self = value.take()?; Ok(()) } + fn reflect_kind(&self) -> bevy_reflect::ReflectKind { + ReflectKind::Value + } fn reflect_ref(&self) -> bevy_reflect::ReflectRef { ReflectRef::Value(self) }