use core::{
any::{Any, TypeId},
marker::Unsize,
ptr::{DynMetadata, Pointee, null},
};
#[doc(hidden)]
pub struct TraitInfo {
type_id: TypeId,
metadata: DynMetadata<dyn Any>,
}
impl TraitInfo {
pub fn new<T, Trait>() -> Self
where
T: Any + Unsize<Trait> + crate::verifier::Verifier<Trait>,
Trait: ?Sized + Pointee<Metadata = DynMetadata<Trait>> + 'static,
{
let type_id = TypeId::of::<Trait>();
let ptr = null::<T>() as *const Trait;
let (_, metadata) = ptr.to_raw_parts();
Self {
type_id,
metadata: unsafe {
core::mem::transmute::<DynMetadata<Trait>, DynMetadata<dyn Any>>(metadata)
},
}
}
#[inline(always)]
pub const fn type_id(&self) -> &TypeId {
&self.type_id
}
pub unsafe fn metadata_unchecked<Trait>(&self) -> DynMetadata<Trait>
where
Trait: ?Sized + Pointee<Metadata = DynMetadata<Trait>> + 'static,
{
debug_assert!(self.type_id == TypeId::of::<Trait>());
unsafe { core::mem::transmute(self.metadata) }
}
}
impl Eq for TraitInfo {}
impl PartialEq for TraitInfo {
fn eq(&self, other: &Self) -> bool {
self.type_id == other.type_id
}
}
impl PartialEq<TypeId> for TraitInfo {
fn eq(&self, other: &TypeId) -> bool {
self.type_id.eq(other)
}
}
impl PartialOrd for TraitInfo {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl PartialOrd<TypeId> for TraitInfo {
fn partial_cmp(&self, other: &TypeId) -> Option<core::cmp::Ordering> {
Some(self.type_id.cmp(other))
}
}
impl Ord for TraitInfo {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.type_id.cmp(&other.type_id)
}
}