bevy_reflect: Add Type type (#14838)
				
					
				
			# Objective Closes #7622. I was working on adding support for reflecting generic functions and found that I wanted to use an argument's `TypeId` for hashing and comparison, but its `TypePath` for debugging and error messaging. While I could just keep them separate, place them in a tuple or a local struct or something, I think I see an opportunity to make a dedicate type for this. Additionally, we can use this type to clean up some duplication amongst the type info structs in a manner similar to #7622. ## Solution Added the `Type` type. This should be seen as the most basic representation of a type apart from `TypeId`. It stores both the `TypeId` of the type as well as its `TypePathTable`. The `Hash` and `PartialEq` implementations rely on the `TypeId`, while the `Debug` implementation relies on the `TypePath`. This makes it especially useful as a key in a `HashMap` since we get the speed of the `TypeId` hashing/comparisons with the readability of `TypePath`. With this type, we're able to reduce the duplication across the type info structs by removing individual fields for `TypeId` and `TypePathTable`, replacing them with a single `Type` field. Similarly, we can remove many duplicate methods and replace it with a macro that delegates to the stored `Type`. ### Caveats It should be noted that this type is currently 3x larger than `TypeId`. On my machine, it's 48 bytes compared to `TypeId`'s 16. While this doesn't matter for `TypeInfo` since it would contain that data regardless, it is something to keep in mind when using elsewhere. ## Testing All tests should pass as normal: ``` cargo test --package bevy_reflect ``` --- ## Showcase `bevy_reflect` now exports a `Type` struct. This type contains both the `TypeId` and the `TypePathTable` of the given type, allowing it to be used like `TypeId` but have the debuggability of `TypePath`. ```rust // We can create this for any type implementing `TypePath`: let ty = Type::of::<String>(); // It has `Hash` and `Eq` impls powered by `TypeId`, making it useful for maps: let mut map = HashMap::<Type, i32>::new(); map.insert(ty, 25); // And it has a human-readable `Debug` representation: let debug = format!("{:?}", map); assert_eq!(debug, "{alloc::string::String: 25}"); ``` ## Migration Guide Certain type info structs now only return their item types as `Type` instead of exposing direct methods on them. The following methods have been removed: - `ArrayInfo::item_type_path_table` - `ArrayInfo::item_type_id` - `ArrayInfo::item_is` - `ListInfo::item_type_path_table` - `ListInfo::item_type_id` - `ListInfo::item_is` - `SetInfo::value_type_path_table` - `SetInfo::value_type_id` - `SetInfo::value_is` - `MapInfo::key_type_path_table` - `MapInfo::key_type_id` - `MapInfo::key_is` - `MapInfo::value_type_path_table` - `MapInfo::value_type_id` - `MapInfo::value_is` Instead, access the `Type` directly using one of the new methods: - `ArrayInfo::item_ty` - `ListInfo::item_ty` - `SetInfo::value_ty` - `MapInfo::key_ty` - `MapInfo::value_ty` For example: ```rust // BEFORE let type_id = array_info.item_type_id(); // AFTER let type_id = array_info.item_ty().id(); ```
This commit is contained in:
		
							parent
							
								
									f9d7a2ca02
								
							
						
					
					
						commit
						3892adcb47
					
				@ -1,10 +1,11 @@
 | 
			
		||||
use crate::type_info::impl_type_methods;
 | 
			
		||||
use crate::{
 | 
			
		||||
    self as bevy_reflect, utility::reflect_hasher, ApplyError, MaybeTyped, PartialReflect, Reflect,
 | 
			
		||||
    ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, TypePathTable,
 | 
			
		||||
    ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath,
 | 
			
		||||
};
 | 
			
		||||
use bevy_reflect_derive::impl_type_path;
 | 
			
		||||
use std::{
 | 
			
		||||
    any::{Any, TypeId},
 | 
			
		||||
    any::Any,
 | 
			
		||||
    fmt::{Debug, Formatter},
 | 
			
		||||
    hash::{Hash, Hasher},
 | 
			
		||||
};
 | 
			
		||||
@ -77,11 +78,9 @@ pub trait Array: PartialReflect {
 | 
			
		||||
/// A container for compile-time array info.
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct ArrayInfo {
 | 
			
		||||
    type_path: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    item_info: fn() -> Option<&'static TypeInfo>,
 | 
			
		||||
    item_type_path: TypePathTable,
 | 
			
		||||
    item_type_id: TypeId,
 | 
			
		||||
    item_ty: Type,
 | 
			
		||||
    capacity: usize,
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
    docs: Option<&'static str>,
 | 
			
		||||
@ -98,11 +97,9 @@ impl ArrayInfo {
 | 
			
		||||
        capacity: usize,
 | 
			
		||||
    ) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            type_path: TypePathTable::of::<TArray>(),
 | 
			
		||||
            type_id: TypeId::of::<TArray>(),
 | 
			
		||||
            ty: Type::of::<TArray>(),
 | 
			
		||||
            item_info: TItem::maybe_type_info,
 | 
			
		||||
            item_type_path: TypePathTable::of::<TItem>(),
 | 
			
		||||
            item_type_id: TypeId::of::<TItem>(),
 | 
			
		||||
            item_ty: Type::of::<TItem>(),
 | 
			
		||||
            capacity,
 | 
			
		||||
            #[cfg(feature = "documentation")]
 | 
			
		||||
            docs: None,
 | 
			
		||||
@ -120,32 +117,7 @@ impl ArrayInfo {
 | 
			
		||||
        self.capacity
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the array.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the array.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the array.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the array type.
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeInfo`] of the array item.
 | 
			
		||||
    ///
 | 
			
		||||
@ -155,21 +127,11 @@ impl ArrayInfo {
 | 
			
		||||
        (self.item_info)()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the array item.
 | 
			
		||||
    /// The [type] of the array item.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn item_type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.item_type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the array item.
 | 
			
		||||
    pub fn item_type_id(&self) -> TypeId {
 | 
			
		||||
        self.item_type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the array item type.
 | 
			
		||||
    pub fn item_is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.item_type_id
 | 
			
		||||
    /// [type]: Type
 | 
			
		||||
    pub fn item_ty(&self) -> Type {
 | 
			
		||||
        self.item_ty
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The docstring of this array, if any.
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
use crate::attributes::{impl_custom_attribute_methods, CustomAttributes};
 | 
			
		||||
use crate::{DynamicEnum, PartialReflect, TypePath, TypePathTable, VariantInfo, VariantType};
 | 
			
		||||
use crate::type_info::impl_type_methods;
 | 
			
		||||
use crate::{DynamicEnum, PartialReflect, Type, TypePath, VariantInfo, VariantType};
 | 
			
		||||
use bevy_utils::HashMap;
 | 
			
		||||
use std::any::{Any, TypeId};
 | 
			
		||||
use std::slice::Iter;
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
 | 
			
		||||
@ -135,8 +135,7 @@ pub trait Enum: PartialReflect {
 | 
			
		||||
/// A container for compile-time enum info, used by [`TypeInfo`](crate::TypeInfo).
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct EnumInfo {
 | 
			
		||||
    type_path: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    variants: Box<[VariantInfo]>,
 | 
			
		||||
    variant_names: Box<[&'static str]>,
 | 
			
		||||
    variant_indices: HashMap<&'static str, usize>,
 | 
			
		||||
@ -162,8 +161,7 @@ impl EnumInfo {
 | 
			
		||||
        let variant_names = variants.iter().map(VariantInfo::name).collect();
 | 
			
		||||
 | 
			
		||||
        Self {
 | 
			
		||||
            type_path: TypePathTable::of::<TEnum>(),
 | 
			
		||||
            type_id: TypeId::of::<TEnum>(),
 | 
			
		||||
            ty: Type::of::<TEnum>(),
 | 
			
		||||
            variants: variants.to_vec().into_boxed_slice(),
 | 
			
		||||
            variant_names,
 | 
			
		||||
            variant_indices,
 | 
			
		||||
@ -231,32 +229,7 @@ impl EnumInfo {
 | 
			
		||||
        self.variants.len()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the value.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the value.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the enum.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the enum type.
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The docstring of this enum, if any.
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
use crate::attributes::{impl_custom_attribute_methods, CustomAttributes};
 | 
			
		||||
use crate::{MaybeTyped, PartialReflect, TypeInfo, TypePath, TypePathTable};
 | 
			
		||||
use std::any::{Any, TypeId};
 | 
			
		||||
use crate::type_info::impl_type_methods;
 | 
			
		||||
use crate::{MaybeTyped, PartialReflect, Type, TypeInfo, TypePath};
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
 | 
			
		||||
/// The named field of a reflected struct.
 | 
			
		||||
@ -8,8 +8,7 @@ use std::sync::Arc;
 | 
			
		||||
pub struct NamedField {
 | 
			
		||||
    name: &'static str,
 | 
			
		||||
    type_info: fn() -> Option<&'static TypeInfo>,
 | 
			
		||||
    type_path: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    custom_attributes: Arc<CustomAttributes>,
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
    docs: Option<&'static str>,
 | 
			
		||||
@ -21,8 +20,7 @@ impl NamedField {
 | 
			
		||||
        Self {
 | 
			
		||||
            name,
 | 
			
		||||
            type_info: T::maybe_type_info,
 | 
			
		||||
            type_path: TypePathTable::of::<T>(),
 | 
			
		||||
            type_id: TypeId::of::<T>(),
 | 
			
		||||
            ty: Type::of::<T>(),
 | 
			
		||||
            custom_attributes: Arc::new(CustomAttributes::default()),
 | 
			
		||||
            #[cfg(feature = "documentation")]
 | 
			
		||||
            docs: None,
 | 
			
		||||
@ -57,32 +55,7 @@ impl NamedField {
 | 
			
		||||
        (self.type_info)()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the field.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the field.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the field.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the field type.
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The docstring of this field, if any.
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
@ -98,8 +71,7 @@ impl NamedField {
 | 
			
		||||
pub struct UnnamedField {
 | 
			
		||||
    index: usize,
 | 
			
		||||
    type_info: fn() -> Option<&'static TypeInfo>,
 | 
			
		||||
    type_path: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    custom_attributes: Arc<CustomAttributes>,
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
    docs: Option<&'static str>,
 | 
			
		||||
@ -110,8 +82,7 @@ impl UnnamedField {
 | 
			
		||||
        Self {
 | 
			
		||||
            index,
 | 
			
		||||
            type_info: T::maybe_type_info,
 | 
			
		||||
            type_path: TypePathTable::of::<T>(),
 | 
			
		||||
            type_id: TypeId::of::<T>(),
 | 
			
		||||
            ty: Type::of::<T>(),
 | 
			
		||||
            custom_attributes: Arc::new(CustomAttributes::default()),
 | 
			
		||||
            #[cfg(feature = "documentation")]
 | 
			
		||||
            docs: None,
 | 
			
		||||
@ -146,32 +117,7 @@ impl UnnamedField {
 | 
			
		||||
        (self.type_info)()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the field.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the field.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the field.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the field type.
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The docstring of this field, if any.
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
use alloc::borrow::Cow;
 | 
			
		||||
 | 
			
		||||
use crate::func::args::{GetOwnership, Ownership};
 | 
			
		||||
use crate::TypePath;
 | 
			
		||||
use crate::type_info::impl_type_methods;
 | 
			
		||||
use crate::{Type, TypePath};
 | 
			
		||||
 | 
			
		||||
/// Type information for an [`Arg`] used in a [`DynamicFunction`] or [`DynamicFunctionMut`].
 | 
			
		||||
///
 | 
			
		||||
@ -16,10 +17,10 @@ pub struct ArgInfo {
 | 
			
		||||
    name: Option<Cow<'static, str>>,
 | 
			
		||||
    /// The ownership of the argument.
 | 
			
		||||
    ownership: Ownership,
 | 
			
		||||
    /// The [type path] of the argument.
 | 
			
		||||
    /// The [type] of the argument.
 | 
			
		||||
    ///
 | 
			
		||||
    /// [type path]: TypePath::type_path
 | 
			
		||||
    type_path: &'static str,
 | 
			
		||||
    /// [type]: Type
 | 
			
		||||
    ty: Type,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl ArgInfo {
 | 
			
		||||
@ -31,7 +32,7 @@ impl ArgInfo {
 | 
			
		||||
            index,
 | 
			
		||||
            name: None,
 | 
			
		||||
            ownership: T::ownership(),
 | 
			
		||||
            type_path: T::type_path(),
 | 
			
		||||
            ty: Type::of::<T>(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -72,12 +73,7 @@ impl ArgInfo {
 | 
			
		||||
        self.ownership
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [type path] of the argument.
 | 
			
		||||
    ///
 | 
			
		||||
    /// [type path]: TypePath::type_path
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// Get an ID representing the argument.
 | 
			
		||||
    ///
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,8 @@ use alloc::borrow::Cow;
 | 
			
		||||
use bevy_utils::all_tuples;
 | 
			
		||||
 | 
			
		||||
use crate::func::args::{ArgInfo, GetOwnership, Ownership};
 | 
			
		||||
use crate::TypePath;
 | 
			
		||||
use crate::type_info::impl_type_methods;
 | 
			
		||||
use crate::{Type, TypePath};
 | 
			
		||||
 | 
			
		||||
/// Type information for a [`DynamicFunction`] or [`DynamicFunctionMut`].
 | 
			
		||||
///
 | 
			
		||||
@ -140,7 +141,7 @@ impl FunctionInfo {
 | 
			
		||||
/// [`DynamicFunctionMut`]: crate::func::DynamicFunctionMut
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct ReturnInfo {
 | 
			
		||||
    type_path: &'static str,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    ownership: Ownership,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -148,17 +149,14 @@ impl ReturnInfo {
 | 
			
		||||
    /// Create a new [`ReturnInfo`] representing the given type, `T`.
 | 
			
		||||
    pub fn new<T: TypePath + GetOwnership>() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            type_path: T::type_path(),
 | 
			
		||||
            ty: Type::of::<T>(),
 | 
			
		||||
            ownership: T::ownership(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The type path of the return type.
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The ownership of the return type.
 | 
			
		||||
    /// The ownership of this type.
 | 
			
		||||
    pub fn ownership(&self) -> Ownership {
 | 
			
		||||
        self.ownership
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1719,10 +1719,10 @@ mod tests {
 | 
			
		||||
        let info = MyList::type_info().as_list().unwrap();
 | 
			
		||||
 | 
			
		||||
        assert!(info.is::<MyList>());
 | 
			
		||||
        assert!(info.item_is::<usize>());
 | 
			
		||||
        assert!(info.item_ty().is::<usize>());
 | 
			
		||||
        assert!(info.item_info().unwrap().is::<usize>());
 | 
			
		||||
        assert_eq!(MyList::type_path(), info.type_path());
 | 
			
		||||
        assert_eq!(usize::type_path(), info.item_type_path_table().path());
 | 
			
		||||
        assert_eq!(usize::type_path(), info.item_ty().path());
 | 
			
		||||
 | 
			
		||||
        let value: &dyn Reflect = &vec![123_usize];
 | 
			
		||||
        let info = value.get_represented_type_info().unwrap();
 | 
			
		||||
@ -1735,10 +1735,10 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
            let info = MySmallVec::type_info().as_list().unwrap();
 | 
			
		||||
            assert!(info.is::<MySmallVec>());
 | 
			
		||||
            assert!(info.item_is::<String>());
 | 
			
		||||
            assert!(info.item_ty().is::<String>());
 | 
			
		||||
            assert!(info.item_info().unwrap().is::<String>());
 | 
			
		||||
            assert_eq!(MySmallVec::type_path(), info.type_path());
 | 
			
		||||
            assert_eq!(String::type_path(), info.item_type_path_table().path());
 | 
			
		||||
            assert_eq!(String::type_path(), info.item_ty().path());
 | 
			
		||||
 | 
			
		||||
            let value: MySmallVec = smallvec::smallvec![String::default(); 2];
 | 
			
		||||
            let value: &dyn Reflect = &value;
 | 
			
		||||
@ -1751,10 +1751,10 @@ mod tests {
 | 
			
		||||
 | 
			
		||||
        let info = MyArray::type_info().as_array().unwrap();
 | 
			
		||||
        assert!(info.is::<MyArray>());
 | 
			
		||||
        assert!(info.item_is::<usize>());
 | 
			
		||||
        assert!(info.item_ty().is::<usize>());
 | 
			
		||||
        assert!(info.item_info().unwrap().is::<usize>());
 | 
			
		||||
        assert_eq!(MyArray::type_path(), info.type_path());
 | 
			
		||||
        assert_eq!(usize::type_path(), info.item_type_path_table().path());
 | 
			
		||||
        assert_eq!(usize::type_path(), info.item_ty().path());
 | 
			
		||||
        assert_eq!(3, info.capacity());
 | 
			
		||||
 | 
			
		||||
        let value: &dyn Reflect = &[1usize, 2usize, 3usize];
 | 
			
		||||
@ -1779,13 +1779,10 @@ mod tests {
 | 
			
		||||
        let info = MyCowSlice::type_info().as_list().unwrap();
 | 
			
		||||
 | 
			
		||||
        assert!(info.is::<MyCowSlice>());
 | 
			
		||||
        assert!(info.item_is::<u8>());
 | 
			
		||||
        assert!(info.item_ty().is::<u8>());
 | 
			
		||||
        assert!(info.item_info().unwrap().is::<u8>());
 | 
			
		||||
        assert_eq!(std::any::type_name::<MyCowSlice>(), info.type_path());
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            std::any::type_name::<u8>(),
 | 
			
		||||
            info.item_type_path_table().path()
 | 
			
		||||
        );
 | 
			
		||||
        assert_eq!(std::any::type_name::<u8>(), info.item_ty().path());
 | 
			
		||||
 | 
			
		||||
        let value: &dyn Reflect = &Cow::<'static, [u8]>::Owned(vec![0, 1, 2, 3]);
 | 
			
		||||
        let info = value.get_represented_type_info().unwrap();
 | 
			
		||||
@ -1797,13 +1794,13 @@ mod tests {
 | 
			
		||||
        let info = MyMap::type_info().as_map().unwrap();
 | 
			
		||||
 | 
			
		||||
        assert!(info.is::<MyMap>());
 | 
			
		||||
        assert!(info.key_is::<usize>());
 | 
			
		||||
        assert!(info.value_is::<f32>());
 | 
			
		||||
        assert!(info.key_ty().is::<usize>());
 | 
			
		||||
        assert!(info.value_ty().is::<f32>());
 | 
			
		||||
        assert!(info.key_info().unwrap().is::<usize>());
 | 
			
		||||
        assert!(info.value_info().unwrap().is::<f32>());
 | 
			
		||||
        assert_eq!(MyMap::type_path(), info.type_path());
 | 
			
		||||
        assert_eq!(usize::type_path(), info.key_type_path_table().path());
 | 
			
		||||
        assert_eq!(f32::type_path(), info.value_type_path_table().path());
 | 
			
		||||
        assert_eq!(usize::type_path(), info.key_ty().path());
 | 
			
		||||
        assert_eq!(f32::type_path(), info.value_ty().path());
 | 
			
		||||
 | 
			
		||||
        let value: &dyn Reflect = &MyMap::new();
 | 
			
		||||
        let info = value.get_represented_type_info().unwrap();
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,14 @@
 | 
			
		||||
use std::any::{Any, TypeId};
 | 
			
		||||
use std::any::Any;
 | 
			
		||||
use std::fmt::{Debug, Formatter};
 | 
			
		||||
use std::hash::{Hash, Hasher};
 | 
			
		||||
 | 
			
		||||
use bevy_reflect_derive::impl_type_path;
 | 
			
		||||
 | 
			
		||||
use crate::type_info::impl_type_methods;
 | 
			
		||||
use crate::utility::reflect_hasher;
 | 
			
		||||
use crate::{
 | 
			
		||||
    self as bevy_reflect, ApplyError, FromReflect, MaybeTyped, PartialReflect, Reflect,
 | 
			
		||||
    ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, TypePathTable,
 | 
			
		||||
    ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// A trait used to power [list-like] operations via [reflection].
 | 
			
		||||
@ -108,11 +109,9 @@ pub trait List: PartialReflect {
 | 
			
		||||
/// A container for compile-time list info.
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct ListInfo {
 | 
			
		||||
    type_path: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    item_info: fn() -> Option<&'static TypeInfo>,
 | 
			
		||||
    item_type_path: TypePathTable,
 | 
			
		||||
    item_type_id: TypeId,
 | 
			
		||||
    item_ty: Type,
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
    docs: Option<&'static str>,
 | 
			
		||||
}
 | 
			
		||||
@ -121,11 +120,9 @@ impl ListInfo {
 | 
			
		||||
    /// Create a new [`ListInfo`].
 | 
			
		||||
    pub fn new<TList: List + TypePath, TItem: FromReflect + MaybeTyped + TypePath>() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            type_path: TypePathTable::of::<TList>(),
 | 
			
		||||
            type_id: TypeId::of::<TList>(),
 | 
			
		||||
            ty: Type::of::<TList>(),
 | 
			
		||||
            item_info: TItem::maybe_type_info,
 | 
			
		||||
            item_type_path: TypePathTable::of::<TItem>(),
 | 
			
		||||
            item_type_id: TypeId::of::<TItem>(),
 | 
			
		||||
            item_ty: Type::of::<TItem>(),
 | 
			
		||||
            #[cfg(feature = "documentation")]
 | 
			
		||||
            docs: None,
 | 
			
		||||
        }
 | 
			
		||||
@ -137,32 +134,7 @@ impl ListInfo {
 | 
			
		||||
        Self { docs, ..self }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the list.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the list.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the list.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the list type.
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeInfo`] of the list item.
 | 
			
		||||
    ///
 | 
			
		||||
@ -172,21 +144,11 @@ impl ListInfo {
 | 
			
		||||
        (self.item_info)()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the list item.
 | 
			
		||||
    /// The [type] of the list item.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn item_type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.item_type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the list item.
 | 
			
		||||
    pub fn item_type_id(&self) -> TypeId {
 | 
			
		||||
        self.item_type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the list item type.
 | 
			
		||||
    pub fn item_is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.item_type_id
 | 
			
		||||
    /// [type]: Type
 | 
			
		||||
    pub fn item_ty(&self) -> Type {
 | 
			
		||||
        self.item_ty
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The docstring of this list, if any.
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
use std::any::{Any, TypeId};
 | 
			
		||||
use std::fmt::{Debug, Formatter};
 | 
			
		||||
 | 
			
		||||
use bevy_reflect_derive::impl_type_path;
 | 
			
		||||
use bevy_utils::{Entry, HashMap};
 | 
			
		||||
 | 
			
		||||
use crate::type_info::impl_type_methods;
 | 
			
		||||
use crate::{
 | 
			
		||||
    self as bevy_reflect, ApplyError, MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut,
 | 
			
		||||
    ReflectOwned, ReflectRef, TypeInfo, TypePath, TypePathTable,
 | 
			
		||||
    ReflectOwned, ReflectRef, Type, TypeInfo, TypePath,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// A trait used to power [map-like] operations via [reflection].
 | 
			
		||||
@ -97,14 +97,11 @@ pub trait Map: PartialReflect {
 | 
			
		||||
/// A container for compile-time map info.
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct MapInfo {
 | 
			
		||||
    type_path: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    key_info: fn() -> Option<&'static TypeInfo>,
 | 
			
		||||
    key_type_path: TypePathTable,
 | 
			
		||||
    key_type_id: TypeId,
 | 
			
		||||
    key_ty: Type,
 | 
			
		||||
    value_info: fn() -> Option<&'static TypeInfo>,
 | 
			
		||||
    value_type_path: TypePathTable,
 | 
			
		||||
    value_type_id: TypeId,
 | 
			
		||||
    value_ty: Type,
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
    docs: Option<&'static str>,
 | 
			
		||||
}
 | 
			
		||||
@ -117,14 +114,11 @@ impl MapInfo {
 | 
			
		||||
        TValue: Reflect + MaybeTyped + TypePath,
 | 
			
		||||
    >() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            type_path: TypePathTable::of::<TMap>(),
 | 
			
		||||
            type_id: TypeId::of::<TMap>(),
 | 
			
		||||
            ty: Type::of::<TMap>(),
 | 
			
		||||
            key_info: TKey::maybe_type_info,
 | 
			
		||||
            key_type_path: TypePathTable::of::<TKey>(),
 | 
			
		||||
            key_type_id: TypeId::of::<TKey>(),
 | 
			
		||||
            key_ty: Type::of::<TKey>(),
 | 
			
		||||
            value_info: TValue::maybe_type_info,
 | 
			
		||||
            value_type_path: TypePathTable::of::<TValue>(),
 | 
			
		||||
            value_type_id: TypeId::of::<TValue>(),
 | 
			
		||||
            value_ty: Type::of::<TValue>(),
 | 
			
		||||
            #[cfg(feature = "documentation")]
 | 
			
		||||
            docs: None,
 | 
			
		||||
        }
 | 
			
		||||
@ -136,32 +130,7 @@ impl MapInfo {
 | 
			
		||||
        Self { docs, ..self }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the map.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the map.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the map.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the map type.
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeInfo`] of the key type.
 | 
			
		||||
    ///
 | 
			
		||||
@ -171,21 +140,11 @@ impl MapInfo {
 | 
			
		||||
        (self.key_info)()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the key type.
 | 
			
		||||
    /// The [type] of the key type.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn key_type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.key_type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the key.
 | 
			
		||||
    pub fn key_type_id(&self) -> TypeId {
 | 
			
		||||
        self.key_type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the key type.
 | 
			
		||||
    pub fn key_is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.key_type_id
 | 
			
		||||
    /// [type]: Type
 | 
			
		||||
    pub fn key_ty(&self) -> Type {
 | 
			
		||||
        self.key_ty
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeInfo`] of the value type.
 | 
			
		||||
@ -196,21 +155,11 @@ impl MapInfo {
 | 
			
		||||
        (self.value_info)()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the value type.
 | 
			
		||||
    /// The [type] of the value type.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn value_type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.value_type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the value.
 | 
			
		||||
    pub fn value_type_id(&self) -> TypeId {
 | 
			
		||||
        self.value_type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the value type.
 | 
			
		||||
    pub fn value_is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.value_type_id
 | 
			
		||||
    /// [type]: Type
 | 
			
		||||
    pub fn value_ty(&self) -> Type {
 | 
			
		||||
        self.value_ty
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The docstring of this map, if any.
 | 
			
		||||
 | 
			
		||||
@ -730,8 +730,8 @@ impl<'a, 'de> Visitor<'de> for ArrayVisitor<'a> {
 | 
			
		||||
    {
 | 
			
		||||
        let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or_default());
 | 
			
		||||
        let registration = get_registration(
 | 
			
		||||
            self.array_info.item_type_id(),
 | 
			
		||||
            self.array_info.item_type_path_table().path(),
 | 
			
		||||
            self.array_info.item_ty().id(),
 | 
			
		||||
            self.array_info.item_ty().path(),
 | 
			
		||||
            self.registry,
 | 
			
		||||
        )?;
 | 
			
		||||
        while let Some(value) = seq.next_element_seed(TypedReflectDeserializer {
 | 
			
		||||
@ -770,8 +770,8 @@ impl<'a, 'de> Visitor<'de> for ListVisitor<'a> {
 | 
			
		||||
    {
 | 
			
		||||
        let mut list = DynamicList::default();
 | 
			
		||||
        let registration = get_registration(
 | 
			
		||||
            self.list_info.item_type_id(),
 | 
			
		||||
            self.list_info.item_type_path_table().path(),
 | 
			
		||||
            self.list_info.item_ty().id(),
 | 
			
		||||
            self.list_info.item_ty().path(),
 | 
			
		||||
            self.registry,
 | 
			
		||||
        )?;
 | 
			
		||||
        while let Some(value) = seq.next_element_seed(TypedReflectDeserializer {
 | 
			
		||||
@ -802,13 +802,13 @@ impl<'a, 'de> Visitor<'de> for MapVisitor<'a> {
 | 
			
		||||
    {
 | 
			
		||||
        let mut dynamic_map = DynamicMap::default();
 | 
			
		||||
        let key_registration = get_registration(
 | 
			
		||||
            self.map_info.key_type_id(),
 | 
			
		||||
            self.map_info.key_type_path_table().path(),
 | 
			
		||||
            self.map_info.key_ty().id(),
 | 
			
		||||
            self.map_info.key_ty().path(),
 | 
			
		||||
            self.registry,
 | 
			
		||||
        )?;
 | 
			
		||||
        let value_registration = get_registration(
 | 
			
		||||
            self.map_info.value_type_id(),
 | 
			
		||||
            self.map_info.value_type_path_table().path(),
 | 
			
		||||
            self.map_info.value_ty().id(),
 | 
			
		||||
            self.map_info.value_ty().path(),
 | 
			
		||||
            self.registry,
 | 
			
		||||
        )?;
 | 
			
		||||
        while let Some(key) = map.next_key_seed(TypedReflectDeserializer {
 | 
			
		||||
@ -844,8 +844,8 @@ impl<'a, 'de> Visitor<'de> for SetVisitor<'a> {
 | 
			
		||||
    {
 | 
			
		||||
        let mut dynamic_set = DynamicSet::default();
 | 
			
		||||
        let value_registration = get_registration(
 | 
			
		||||
            self.set_info.value_type_id(),
 | 
			
		||||
            self.set_info.value_type_path_table().path(),
 | 
			
		||||
            self.set_info.value_ty().id(),
 | 
			
		||||
            self.set_info.value_ty().path(),
 | 
			
		||||
            self.registry,
 | 
			
		||||
        )?;
 | 
			
		||||
        while let Some(value) = set.next_element_seed(TypedReflectDeserializer {
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,13 @@
 | 
			
		||||
use std::any::{Any, TypeId};
 | 
			
		||||
use std::fmt::{Debug, Formatter};
 | 
			
		||||
 | 
			
		||||
use bevy_reflect_derive::impl_type_path;
 | 
			
		||||
use bevy_utils::hashbrown::hash_table::OccupiedEntry as HashTableOccupiedEntry;
 | 
			
		||||
use bevy_utils::hashbrown::HashTable;
 | 
			
		||||
 | 
			
		||||
use crate::type_info::impl_type_methods;
 | 
			
		||||
use crate::{
 | 
			
		||||
    self as bevy_reflect, hash_error, ApplyError, PartialReflect, Reflect, ReflectKind, ReflectMut,
 | 
			
		||||
    ReflectOwned, ReflectRef, TypeInfo, TypePath, TypePathTable,
 | 
			
		||||
    ReflectOwned, ReflectRef, Type, TypeInfo, TypePath,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// A trait used to power [set-like] operations via [reflection].
 | 
			
		||||
@ -82,10 +82,8 @@ pub trait Set: PartialReflect {
 | 
			
		||||
/// A container for compile-time set info.
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct SetInfo {
 | 
			
		||||
    type_path: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
    value_type_path: TypePathTable,
 | 
			
		||||
    value_type_id: TypeId,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    value_ty: Type,
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
    docs: Option<&'static str>,
 | 
			
		||||
}
 | 
			
		||||
@ -94,10 +92,8 @@ impl SetInfo {
 | 
			
		||||
    /// Create a new [`SetInfo`].
 | 
			
		||||
    pub fn new<TSet: Set + TypePath, TValue: Reflect + TypePath>() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            type_path: TypePathTable::of::<TSet>(),
 | 
			
		||||
            type_id: TypeId::of::<TSet>(),
 | 
			
		||||
            value_type_path: TypePathTable::of::<TValue>(),
 | 
			
		||||
            value_type_id: TypeId::of::<TValue>(),
 | 
			
		||||
            ty: Type::of::<TSet>(),
 | 
			
		||||
            value_ty: Type::of::<TValue>(),
 | 
			
		||||
            #[cfg(feature = "documentation")]
 | 
			
		||||
            docs: None,
 | 
			
		||||
        }
 | 
			
		||||
@ -109,48 +105,13 @@ impl SetInfo {
 | 
			
		||||
        Self { docs, ..self }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the set.
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The [type] of the value.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the set.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the set.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the set type.
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the value type.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn value_type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.value_type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the value.
 | 
			
		||||
    pub fn value_type_id(&self) -> TypeId {
 | 
			
		||||
        self.value_type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the value type.
 | 
			
		||||
    pub fn value_is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.value_type_id
 | 
			
		||||
    /// [type]: Type
 | 
			
		||||
    pub fn value_ty(&self) -> Type {
 | 
			
		||||
        self.value_ty
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The docstring of this set, if any.
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,14 @@
 | 
			
		||||
use crate::attributes::{impl_custom_attribute_methods, CustomAttributes};
 | 
			
		||||
use crate::type_info::impl_type_methods;
 | 
			
		||||
use crate::{
 | 
			
		||||
    self as bevy_reflect, ApplyError, NamedField, PartialReflect, Reflect, ReflectKind, ReflectMut,
 | 
			
		||||
    ReflectOwned, ReflectRef, TypeInfo, TypePath, TypePathTable,
 | 
			
		||||
    ReflectOwned, ReflectRef, Type, TypeInfo, TypePath,
 | 
			
		||||
};
 | 
			
		||||
use bevy_reflect_derive::impl_type_path;
 | 
			
		||||
use bevy_utils::HashMap;
 | 
			
		||||
use std::fmt::{Debug, Formatter};
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
use std::{
 | 
			
		||||
    any::{Any, TypeId},
 | 
			
		||||
    borrow::Cow,
 | 
			
		||||
    slice::Iter,
 | 
			
		||||
};
 | 
			
		||||
use std::{borrow::Cow, slice::Iter};
 | 
			
		||||
 | 
			
		||||
/// A trait used to power [struct-like] operations via [reflection].
 | 
			
		||||
///
 | 
			
		||||
@ -78,8 +75,7 @@ pub trait Struct: PartialReflect {
 | 
			
		||||
/// A container for compile-time named struct info.
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct StructInfo {
 | 
			
		||||
    type_path: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    fields: Box<[NamedField]>,
 | 
			
		||||
    field_names: Box<[&'static str]>,
 | 
			
		||||
    field_indices: HashMap<&'static str, usize>,
 | 
			
		||||
@ -105,8 +101,7 @@ impl StructInfo {
 | 
			
		||||
        let field_names = fields.iter().map(NamedField::name).collect();
 | 
			
		||||
 | 
			
		||||
        Self {
 | 
			
		||||
            type_path: TypePathTable::of::<T>(),
 | 
			
		||||
            type_id: TypeId::of::<T>(),
 | 
			
		||||
            ty: Type::of::<T>(),
 | 
			
		||||
            fields: fields.to_vec().into_boxed_slice(),
 | 
			
		||||
            field_names,
 | 
			
		||||
            field_indices,
 | 
			
		||||
@ -162,32 +157,7 @@ impl StructInfo {
 | 
			
		||||
        self.fields.len()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the struct.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the struct.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the struct.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the struct type.
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The docstring of this struct, if any.
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,14 @@
 | 
			
		||||
use bevy_reflect_derive::impl_type_path;
 | 
			
		||||
use bevy_utils::all_tuples;
 | 
			
		||||
 | 
			
		||||
use crate::type_info::impl_type_methods;
 | 
			
		||||
use crate::{
 | 
			
		||||
    self as bevy_reflect, utility::GenericTypePathCell, ApplyError, FromReflect,
 | 
			
		||||
    GetTypeRegistration, MaybeTyped, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo,
 | 
			
		||||
    GetTypeRegistration, MaybeTyped, Reflect, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo,
 | 
			
		||||
    TypePath, TypeRegistration, TypeRegistry, Typed, UnnamedField,
 | 
			
		||||
};
 | 
			
		||||
use crate::{PartialReflect, ReflectKind, TypePathTable};
 | 
			
		||||
use std::any::{Any, TypeId};
 | 
			
		||||
use crate::{PartialReflect, ReflectKind};
 | 
			
		||||
use std::any::Any;
 | 
			
		||||
use std::fmt::{Debug, Formatter};
 | 
			
		||||
use std::slice::Iter;
 | 
			
		||||
 | 
			
		||||
@ -139,8 +140,7 @@ impl GetTupleField for dyn Tuple {
 | 
			
		||||
/// A container for compile-time tuple info.
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct TupleInfo {
 | 
			
		||||
    type_path: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    fields: Box<[UnnamedField]>,
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
    docs: Option<&'static str>,
 | 
			
		||||
@ -155,8 +155,7 @@ impl TupleInfo {
 | 
			
		||||
    ///
 | 
			
		||||
    pub fn new<T: Reflect + TypePath>(fields: &[UnnamedField]) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            type_path: TypePathTable::of::<T>(),
 | 
			
		||||
            type_id: TypeId::of::<T>(),
 | 
			
		||||
            ty: Type::of::<T>(),
 | 
			
		||||
            fields: fields.to_vec().into_boxed_slice(),
 | 
			
		||||
            #[cfg(feature = "documentation")]
 | 
			
		||||
            docs: None,
 | 
			
		||||
@ -184,32 +183,7 @@ impl TupleInfo {
 | 
			
		||||
        self.fields.len()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the tuple.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the tuple.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the tuple.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the tuple type.
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The docstring of this tuple, if any.
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
use bevy_reflect_derive::impl_type_path;
 | 
			
		||||
 | 
			
		||||
use crate::attributes::{impl_custom_attribute_methods, CustomAttributes};
 | 
			
		||||
use crate::type_info::impl_type_methods;
 | 
			
		||||
use crate::{
 | 
			
		||||
    self as bevy_reflect, ApplyError, DynamicTuple, PartialReflect, Reflect, ReflectKind,
 | 
			
		||||
    ReflectMut, ReflectOwned, ReflectRef, Tuple, TypeInfo, TypePath, TypePathTable, UnnamedField,
 | 
			
		||||
    ReflectMut, ReflectOwned, ReflectRef, Tuple, Type, TypeInfo, TypePath, UnnamedField,
 | 
			
		||||
};
 | 
			
		||||
use std::any::{Any, TypeId};
 | 
			
		||||
use std::fmt::{Debug, Formatter};
 | 
			
		||||
use std::slice::Iter;
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
@ -58,8 +58,7 @@ pub trait TupleStruct: PartialReflect {
 | 
			
		||||
/// A container for compile-time tuple struct info.
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct TupleStructInfo {
 | 
			
		||||
    type_path: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    fields: Box<[UnnamedField]>,
 | 
			
		||||
    custom_attributes: Arc<CustomAttributes>,
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
@ -75,8 +74,7 @@ impl TupleStructInfo {
 | 
			
		||||
    ///
 | 
			
		||||
    pub fn new<T: Reflect + TypePath>(fields: &[UnnamedField]) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            type_path: TypePathTable::of::<T>(),
 | 
			
		||||
            type_id: TypeId::of::<T>(),
 | 
			
		||||
            ty: Type::of::<T>(),
 | 
			
		||||
            fields: fields.to_vec().into_boxed_slice(),
 | 
			
		||||
            custom_attributes: Arc::new(CustomAttributes::default()),
 | 
			
		||||
            #[cfg(feature = "documentation")]
 | 
			
		||||
@ -113,32 +111,7 @@ impl TupleStructInfo {
 | 
			
		||||
        self.fields.len()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the struct.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the struct.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the tuple struct.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the tuple struct type.
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The docstring of this struct, if any.
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,10 @@ use crate::{
 | 
			
		||||
    DynamicTupleStruct, EnumInfo, ListInfo, MapInfo, PartialReflect, Reflect, ReflectKind, SetInfo,
 | 
			
		||||
    StructInfo, TupleInfo, TupleStructInfo, TypePath, TypePathTable,
 | 
			
		||||
};
 | 
			
		||||
use core::fmt::Formatter;
 | 
			
		||||
use std::any::{Any, TypeId};
 | 
			
		||||
use std::fmt::Debug;
 | 
			
		||||
use std::hash::Hash;
 | 
			
		||||
use thiserror::Error;
 | 
			
		||||
 | 
			
		||||
/// A static accessor to compile-time type information.
 | 
			
		||||
@ -178,36 +180,33 @@ pub enum TypeInfo {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl TypeInfo {
 | 
			
		||||
    /// The underlying Rust [type].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [type]: Type
 | 
			
		||||
    pub fn ty(&self) -> &Type {
 | 
			
		||||
        match self {
 | 
			
		||||
            Self::Struct(info) => info.ty(),
 | 
			
		||||
            Self::TupleStruct(info) => info.ty(),
 | 
			
		||||
            Self::Tuple(info) => info.ty(),
 | 
			
		||||
            Self::List(info) => info.ty(),
 | 
			
		||||
            Self::Array(info) => info.ty(),
 | 
			
		||||
            Self::Map(info) => info.ty(),
 | 
			
		||||
            Self::Set(info) => info.ty(),
 | 
			
		||||
            Self::Enum(info) => info.ty(),
 | 
			
		||||
            Self::Value(info) => info.ty(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the underlying type.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        match self {
 | 
			
		||||
            Self::Struct(info) => info.type_id(),
 | 
			
		||||
            Self::TupleStruct(info) => info.type_id(),
 | 
			
		||||
            Self::Tuple(info) => info.type_id(),
 | 
			
		||||
            Self::List(info) => info.type_id(),
 | 
			
		||||
            Self::Array(info) => info.type_id(),
 | 
			
		||||
            Self::Map(info) => info.type_id(),
 | 
			
		||||
            Self::Set(info) => info.type_id(),
 | 
			
		||||
            Self::Enum(info) => info.type_id(),
 | 
			
		||||
            Self::Value(info) => info.type_id(),
 | 
			
		||||
        }
 | 
			
		||||
        self.ty().id()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the underlying type.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        match self {
 | 
			
		||||
            Self::Struct(info) => info.type_path_table(),
 | 
			
		||||
            Self::TupleStruct(info) => info.type_path_table(),
 | 
			
		||||
            Self::Tuple(info) => info.type_path_table(),
 | 
			
		||||
            Self::List(info) => info.type_path_table(),
 | 
			
		||||
            Self::Array(info) => info.type_path_table(),
 | 
			
		||||
            Self::Map(info) => info.type_path_table(),
 | 
			
		||||
            Self::Set(info) => info.type_path_table(),
 | 
			
		||||
            Self::Enum(info) => info.type_path_table(),
 | 
			
		||||
            Self::Value(info) => info.type_path_table(),
 | 
			
		||||
        }
 | 
			
		||||
        self.ty().type_path_table()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the underlying type.
 | 
			
		||||
@ -217,12 +216,16 @@ impl TypeInfo {
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
        self.ty().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the underlying type.
 | 
			
		||||
    /// Check if the given type matches this one.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This only compares the [`TypeId`] of the types
 | 
			
		||||
    /// and does not verify they share the same [`TypePath`]
 | 
			
		||||
    /// (though it implies they do).
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id()
 | 
			
		||||
        self.ty().is::<T>()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The docstring of the underlying type, if any.
 | 
			
		||||
@ -287,6 +290,199 @@ impl TypeInfo {
 | 
			
		||||
    impl_cast_method!(as_value: Value => ValueInfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// The base representation of a Rust type.
 | 
			
		||||
///
 | 
			
		||||
/// When possible, it is recommended to use [`&'static TypeInfo`] instead of this
 | 
			
		||||
/// as it provides more information as well as being smaller
 | 
			
		||||
/// (since a reference only takes the same number of bytes as a `usize`).
 | 
			
		||||
///
 | 
			
		||||
/// However, where a static reference to [`TypeInfo`] is not possible,
 | 
			
		||||
/// such as with trait objects and other types that can't implement [`Typed`],
 | 
			
		||||
/// this type can be used instead.
 | 
			
		||||
///
 | 
			
		||||
/// It only requires that the type implements [`TypePath`].
 | 
			
		||||
///
 | 
			
		||||
/// And unlike [`TypeInfo`], this type implements [`Copy`], [`Eq`], and [`Hash`],
 | 
			
		||||
/// making it useful as a key type.
 | 
			
		||||
///
 | 
			
		||||
/// It's especially helpful when compared to [`TypeId`] as it can provide the
 | 
			
		||||
/// actual [type path] when debugging, while still having the same performance
 | 
			
		||||
/// as hashing/comparing [`TypeId`] directly—at the cost of a little more memory.
 | 
			
		||||
///
 | 
			
		||||
/// # Examples
 | 
			
		||||
///
 | 
			
		||||
/// ```
 | 
			
		||||
/// use bevy_reflect::{Type, TypePath};
 | 
			
		||||
///
 | 
			
		||||
/// fn assert_char<T: ?Sized + TypePath>(t: &T) -> Result<(), String> {
 | 
			
		||||
///     let ty = Type::of::<T>();
 | 
			
		||||
///     if Type::of::<char>() == ty {
 | 
			
		||||
///         Ok(())
 | 
			
		||||
///     } else {
 | 
			
		||||
///         Err(format!("expected `char`, got `{}`", ty.path()))
 | 
			
		||||
///     }
 | 
			
		||||
/// }
 | 
			
		||||
///
 | 
			
		||||
/// assert_eq!(
 | 
			
		||||
///     assert_char(&'a'),
 | 
			
		||||
///     Ok(())
 | 
			
		||||
/// );
 | 
			
		||||
/// assert_eq!(
 | 
			
		||||
///     assert_char(&String::from("Hello, world!")),
 | 
			
		||||
///     Err(String::from("expected `char`, got `alloc::string::String`"))
 | 
			
		||||
/// );
 | 
			
		||||
/// ```
 | 
			
		||||
///
 | 
			
		||||
/// [`&'static TypeInfo`]: TypeInfo
 | 
			
		||||
#[derive(Copy, Clone)]
 | 
			
		||||
pub struct Type {
 | 
			
		||||
    type_path_table: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Type {
 | 
			
		||||
    /// Create a new [`Type`] from a type that implements [`TypePath`].
 | 
			
		||||
    pub fn of<T: TypePath + ?Sized>() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            type_path_table: TypePathTable::of::<T>(),
 | 
			
		||||
            type_id: TypeId::of::<T>(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the [`TypeId`] of the type.
 | 
			
		||||
    pub fn id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// See [`TypePath::type_path`].
 | 
			
		||||
    pub fn path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table.path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// See [`TypePath::short_type_path`].
 | 
			
		||||
    pub fn short_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table.short_path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// See [`TypePath::type_ident`].
 | 
			
		||||
    pub fn ident(&self) -> Option<&'static str> {
 | 
			
		||||
        self.type_path_table.ident()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// See [`TypePath::crate_name`].
 | 
			
		||||
    pub fn crate_name(&self) -> Option<&'static str> {
 | 
			
		||||
        self.type_path_table.crate_name()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// See [`TypePath::module_path`].
 | 
			
		||||
    pub fn module_path(&self) -> Option<&'static str> {
 | 
			
		||||
        self.type_path_table.module_path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of this.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path_table
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches this one.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This only compares the [`TypeId`] of the types
 | 
			
		||||
    /// and does not verify they share the same [`TypePath`]
 | 
			
		||||
    /// (though it implies they do).
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// This implementation will only output the [type path] of the type.
 | 
			
		||||
///
 | 
			
		||||
/// If you need to include the [`TypeId`] in the output,
 | 
			
		||||
/// you can access it through [`Type::id`].
 | 
			
		||||
///
 | 
			
		||||
/// [type path]: TypePath
 | 
			
		||||
impl Debug for Type {
 | 
			
		||||
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
 | 
			
		||||
        write!(f, "{}", self.type_path_table.path())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Eq for Type {}
 | 
			
		||||
 | 
			
		||||
/// This implementation purely relies on the [`TypeId`] of the type,
 | 
			
		||||
/// and not on the [type path].
 | 
			
		||||
///
 | 
			
		||||
/// [type path]: TypePath
 | 
			
		||||
impl PartialEq for Type {
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn eq(&self, other: &Self) -> bool {
 | 
			
		||||
        self.type_id == other.type_id
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// This implementation purely relies on the [`TypeId`] of the type,
 | 
			
		||||
/// and not on the [type path].
 | 
			
		||||
///
 | 
			
		||||
/// [type path]: TypePath
 | 
			
		||||
impl Hash for Type {
 | 
			
		||||
    #[inline]
 | 
			
		||||
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
 | 
			
		||||
        self.type_id.hash(state);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
macro_rules! impl_type_methods {
 | 
			
		||||
    ($field:ident) => {
 | 
			
		||||
        /// The underlying Rust [type].
 | 
			
		||||
        ///
 | 
			
		||||
        /// [type]: crate::type_info::Type
 | 
			
		||||
        pub fn ty(&self) -> &$crate::type_info::Type {
 | 
			
		||||
            &self.$field
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// The [`TypeId`] of this type.
 | 
			
		||||
        ///
 | 
			
		||||
        /// [`TypeId`]: std::any::TypeId
 | 
			
		||||
        pub fn type_id(&self) -> ::std::any::TypeId {
 | 
			
		||||
            self.$field.id()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// The [stable, full type path] of this type.
 | 
			
		||||
        ///
 | 
			
		||||
        /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
        ///
 | 
			
		||||
        /// [stable, full type path]: TypePath
 | 
			
		||||
        /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
        pub fn type_path(&self) -> &'static str {
 | 
			
		||||
            self.$field.path()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// A representation of the type path of this type.
 | 
			
		||||
        ///
 | 
			
		||||
        /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
        ///
 | 
			
		||||
        /// [`TypePath`]: crate::type_path::TypePath
 | 
			
		||||
        pub fn type_path_table(&self) -> &$crate::type_path::TypePathTable {
 | 
			
		||||
            &self.$field.type_path_table()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// Check if the given type matches this one.
 | 
			
		||||
        ///
 | 
			
		||||
        /// This only compares the [`TypeId`] of the types
 | 
			
		||||
        /// and does not verify they share the same [`TypePath`]
 | 
			
		||||
        /// (though it implies they do).
 | 
			
		||||
        ///
 | 
			
		||||
        /// [`TypeId`]: std::any::TypeId
 | 
			
		||||
        /// [`TypePath`]: crate::type_path::TypePath
 | 
			
		||||
        pub fn is<T: ::std::any::Any>(&self) -> bool {
 | 
			
		||||
            self.$field.is::<T>()
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(crate) use impl_type_methods;
 | 
			
		||||
 | 
			
		||||
/// A container for compile-time info related to general value types, including primitives.
 | 
			
		||||
///
 | 
			
		||||
/// This typically represents a type which cannot be broken down any further. This is often
 | 
			
		||||
@ -297,8 +493,7 @@ impl TypeInfo {
 | 
			
		||||
/// it _as_ a struct. It therefore makes more sense to represent it as a [`ValueInfo`].
 | 
			
		||||
#[derive(Debug, Clone)]
 | 
			
		||||
pub struct ValueInfo {
 | 
			
		||||
    type_path: TypePathTable,
 | 
			
		||||
    type_id: TypeId,
 | 
			
		||||
    ty: Type,
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
    docs: Option<&'static str>,
 | 
			
		||||
}
 | 
			
		||||
@ -306,8 +501,7 @@ pub struct ValueInfo {
 | 
			
		||||
impl ValueInfo {
 | 
			
		||||
    pub fn new<T: Reflect + TypePath + ?Sized>() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            type_path: TypePathTable::of::<T>(),
 | 
			
		||||
            type_id: TypeId::of::<T>(),
 | 
			
		||||
            ty: Type::of::<T>(),
 | 
			
		||||
            #[cfg(feature = "documentation")]
 | 
			
		||||
            docs: None,
 | 
			
		||||
        }
 | 
			
		||||
@ -319,32 +513,7 @@ impl ValueInfo {
 | 
			
		||||
        Self { docs: doc, ..self }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// A representation of the type path of the value.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Provides dynamic access to all methods on [`TypePath`].
 | 
			
		||||
    pub fn type_path_table(&self) -> &TypePathTable {
 | 
			
		||||
        &self.type_path
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [stable, full type path] of the value.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Use [`type_path_table`] if you need access to the other methods on [`TypePath`].
 | 
			
		||||
    ///
 | 
			
		||||
    /// [stable, full type path]: TypePath
 | 
			
		||||
    /// [`type_path_table`]: Self::type_path_table
 | 
			
		||||
    pub fn type_path(&self) -> &'static str {
 | 
			
		||||
        self.type_path_table().path()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// The [`TypeId`] of the value.
 | 
			
		||||
    pub fn type_id(&self) -> TypeId {
 | 
			
		||||
        self.type_id
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Check if the given type matches the value type.
 | 
			
		||||
    pub fn is<T: Any>(&self) -> bool {
 | 
			
		||||
        TypeId::of::<T>() == self.type_id
 | 
			
		||||
    }
 | 
			
		||||
    impl_type_methods!(ty);
 | 
			
		||||
 | 
			
		||||
    /// The docstring of this dynamic value, if any.
 | 
			
		||||
    #[cfg(feature = "documentation")]
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user