rune/runtime/
type_info.rs1use core::fmt;
2use core::hash;
3
4use crate as rune;
5use crate::alloc::prelude::*;
6use crate::compile::Named;
7use crate::hash::Hash;
8use crate::sync::Arc;
9use crate::{Any, TypeHash};
10
11use super::Rtti;
12
13#[derive(Debug, TryClone, PartialEq, Eq)]
14enum TypeInfoKind {
15 Any(AnyTypeInfo),
17 Runtime(Arc<Rtti>),
19}
20
21#[derive(TryClone, PartialEq, Eq)]
29#[non_exhaustive]
30pub struct TypeInfo {
31 kind: TypeInfoKind,
32}
33
34impl TypeInfo {
35 #[inline]
36 const fn new(kind: TypeInfoKind) -> Self {
37 Self { kind }
38 }
39
40 pub const fn empty() -> Self {
42 Self::new(TypeInfoKind::Any(AnyTypeInfo {
43 full_name: |f| write!(f, "empty"),
44 hash: crate::hash!(::std::empty::Empty),
45 }))
46 }
47
48 #[inline]
50 pub const fn any<T>() -> Self
51 where
52 T: Any,
53 {
54 Self::any_type_info(T::ANY_TYPE_INFO)
55 }
56
57 #[inline]
59 pub const fn named<T>() -> Self
60 where
61 T: Named + TypeHash,
62 {
63 Self::any_type_info(AnyTypeInfo::new(T::full_name, T::HASH))
64 }
65
66 #[doc(hidden)]
68 #[inline]
69 pub(crate) const fn any_type_info(type_info: AnyTypeInfo) -> Self {
70 Self::new(TypeInfoKind::Any(type_info))
71 }
72
73 #[inline]
74 pub(crate) const fn rtti(rtti: Arc<Rtti>) -> Self {
75 Self::new(TypeInfoKind::Runtime(rtti))
76 }
77
78 #[cfg(feature = "emit")]
79 pub(crate) fn type_hash(&self) -> Hash {
80 match &self.kind {
81 TypeInfoKind::Any(ty) => ty.hash,
82 TypeInfoKind::Runtime(ty) => ty.type_hash(),
83 }
84 }
85}
86
87impl fmt::Debug for TypeInfo {
88 #[inline]
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 self.kind.fmt(f)
91 }
92}
93
94impl fmt::Display for TypeInfo {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 match &self.kind {
97 TypeInfoKind::Runtime(rtti) => {
98 write!(f, "{}", rtti.item)?;
99 }
100 TypeInfoKind::Any(info) => {
101 write!(f, "{info}")?;
102 }
103 }
104
105 Ok(())
106 }
107}
108
109impl From<AnyTypeInfo> for TypeInfo {
110 #[inline]
111 fn from(type_info: AnyTypeInfo) -> Self {
112 Self::any_type_info(type_info)
113 }
114}
115
116#[derive(Debug, TryClone, Clone, Copy)]
118#[try_clone(copy)]
119pub struct AnyTypeInfo {
120 pub(crate) full_name: FullNameFn,
122 pub(crate) hash: Hash,
124}
125
126impl AnyTypeInfo {
127 pub(crate) const fn new(full_name: FullNameFn, hash: Hash) -> Self {
129 Self { full_name, hash }
130 }
131}
132
133impl fmt::Display for AnyTypeInfo {
134 #[inline]
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 (self.full_name)(f)
137 }
138}
139
140pub type FullNameFn = fn(&mut fmt::Formatter<'_>) -> fmt::Result;
141
142impl PartialEq for AnyTypeInfo {
143 #[inline]
144 fn eq(&self, other: &Self) -> bool {
145 self.hash == other.hash
146 }
147}
148
149impl Eq for AnyTypeInfo {}
150
151impl hash::Hash for AnyTypeInfo {
152 #[inline]
153 fn hash<H: hash::Hasher>(&self, state: &mut H) {
154 self.hash.hash(state);
155 }
156}