use crate::{TypePath, TypePathTable};
use core::any::{Any, TypeId};
use core::fmt::{Debug, Formatter};
use core::hash::Hash;
#[derive(Copy, Clone)]
pub struct Type {
type_path_table: TypePathTable,
type_id: TypeId,
}
impl Type {
pub fn of<T: TypePath + ?Sized>() -> Self {
Self {
type_path_table: TypePathTable::of::<T>(),
type_id: TypeId::of::<T>(),
}
}
#[inline]
pub fn id(&self) -> TypeId {
self.type_id
}
pub fn path(&self) -> &'static str {
self.type_path_table.path()
}
pub fn short_path(&self) -> &'static str {
self.type_path_table.short_path()
}
pub fn ident(&self) -> Option<&'static str> {
self.type_path_table.ident()
}
pub fn crate_name(&self) -> Option<&'static str> {
self.type_path_table.crate_name()
}
pub fn module_path(&self) -> Option<&'static str> {
self.type_path_table.module_path()
}
pub fn type_path_table(&self) -> &TypePathTable {
&self.type_path_table
}
pub fn is<T: Any>(&self) -> bool {
TypeId::of::<T>() == self.type_id
}
}
impl Debug for Type {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.type_path_table.path())
}
}
impl Eq for Type {}
impl PartialEq for Type {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.type_id == other.type_id
}
}
impl Hash for Type {
#[inline]
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.type_id.hash(state);
}
}
macro_rules! impl_type_methods {
($field:ident) => {
$crate::ty::impl_type_methods!(self => {
&self.$field
});
};
($self:ident => $expr:expr) => {
pub fn ty(&$self) -> &$crate::ty::Type {
$expr
}
pub fn type_id(&self) -> ::core::any::TypeId {
self.ty().id()
}
pub fn type_path(&self) -> &'static str {
self.ty().path()
}
pub fn type_path_table(&self) -> &$crate::type_path::TypePathTable {
&self.ty().type_path_table()
}
pub fn is<T: ::core::any::Any>(&self) -> bool {
self.ty().is::<T>()
}
};
}
pub(crate) use impl_type_methods;