rune/runtime/
type_info.rsuse core::fmt;
use core::hash;
use crate as rune;
use crate::alloc::prelude::*;
use crate::compile::Named;
use crate::hash::Hash;
use crate::{Any, TypeHash};
use ::rust_alloc::sync::Arc;
use super::Rtti;
#[derive(Debug, TryClone, PartialEq, Eq)]
enum TypeInfoKind {
Any(AnyTypeInfo),
Runtime(Arc<Rtti>),
}
#[derive(TryClone, PartialEq, Eq)]
#[non_exhaustive]
pub struct TypeInfo {
kind: TypeInfoKind,
}
impl TypeInfo {
#[inline]
const fn new(kind: TypeInfoKind) -> Self {
Self { kind }
}
pub const fn empty() -> Self {
Self::new(TypeInfoKind::Any(AnyTypeInfo {
full_name: |f| write!(f, "empty"),
hash: crate::hash!(::std::empty::Empty),
}))
}
#[inline]
pub const fn any<T>() -> Self
where
T: Any,
{
Self::any_type_info(T::ANY_TYPE_INFO)
}
#[inline]
pub const fn named<T>() -> Self
where
T: Named + TypeHash,
{
Self::any_type_info(AnyTypeInfo::new(T::full_name, T::HASH))
}
#[doc(hidden)]
#[inline]
pub(crate) const fn any_type_info(type_info: AnyTypeInfo) -> Self {
Self::new(TypeInfoKind::Any(type_info))
}
#[inline]
pub(crate) const fn rtti(rtti: Arc<Rtti>) -> Self {
Self::new(TypeInfoKind::Runtime(rtti))
}
#[cfg(feature = "emit")]
pub(crate) fn type_hash(&self) -> Hash {
match &self.kind {
TypeInfoKind::Any(ty) => ty.hash,
TypeInfoKind::Runtime(ty) => ty.type_hash(),
}
}
}
impl fmt::Debug for TypeInfo {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.kind.fmt(f)
}
}
impl fmt::Display for TypeInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.kind {
TypeInfoKind::Runtime(rtti) => {
write!(f, "{}", rtti.item)?;
}
TypeInfoKind::Any(info) => {
write!(f, "{info}")?;
}
}
Ok(())
}
}
impl From<AnyTypeInfo> for TypeInfo {
#[inline]
fn from(type_info: AnyTypeInfo) -> Self {
Self::any_type_info(type_info)
}
}
#[derive(Debug, TryClone, Clone, Copy)]
#[try_clone(copy)]
pub struct AnyTypeInfo {
pub(crate) full_name: FullNameFn,
pub(crate) hash: Hash,
}
impl AnyTypeInfo {
pub(crate) const fn new(full_name: FullNameFn, hash: Hash) -> Self {
Self { full_name, hash }
}
}
impl fmt::Display for AnyTypeInfo {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
(self.full_name)(f)
}
}
pub type FullNameFn = fn(&mut fmt::Formatter<'_>) -> fmt::Result;
impl PartialEq for AnyTypeInfo {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.hash == other.hash
}
}
impl Eq for AnyTypeInfo {}
impl hash::Hash for AnyTypeInfo {
#[inline]
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.hash.hash(state);
}
}