1#[cfg(feature = "im")]
2mod im;
3pub mod internal;
4#[cfg(feature = "serde")]
5mod serde;
6
7use internal::helper_string_non_ascii;
8use lazy_static::lazy_static;
9pub use ossa_typeable_derive::Typeable;
10use sha2::{Digest, Sha256};
11use std::fmt;
12
13use crate::internal::{
14 helper_type_args_count, helper_type_constructor, helper_type_ident, helper_usize,
15};
16
17#[derive(Copy, Clone, Debug, PartialEq, Eq)]
19pub struct TypeId([u8; 32]);
20
21impl TypeId {
22 pub fn new(h: [u8; 32]) -> TypeId {
23 TypeId(h)
24 }
25
26 pub fn identifier(&self) -> [u8; 32] {
27 self.0
28 }
29}
30
31impl fmt::Display for TypeId {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
33 write!(f, "0x")?;
34 for b in self.0 {
35 write!(f, "{:02X}", b)?;
36 }
37 Ok(())
38 }
39}
40
41impl AsRef<[u8]> for TypeId {
42 fn as_ref(&self) -> &[u8] {
43 &self.0
44 }
45}
46
47pub trait Typeable {
95 fn type_ident() -> TypeId; }
98
99macro_rules! derive_typeable_primitive {
100 ( $type_name: ident ) => {
101 derive_typeable_primitive!($type_name, $type_name);
102 };
103 ( $type_name: ident, $mod_name: ident ) => {
104 mod $mod_name {
105 use super::*;
106
107 lazy_static! {
108 static ref DERIVED_TYPE_ID: TypeId = {
109 let mut h = Sha256::new();
110 helper_type_constructor(&mut h, stringify!($type_name));
111 TypeId(h.finalize().into())
112 };
113 }
114
115 impl Typeable for $type_name {
116 fn type_ident() -> TypeId {
117 *DERIVED_TYPE_ID
118 }
119 }
120 }
121 };
122}
123
124derive_typeable_primitive!(bool);
125derive_typeable_primitive!(char);
126derive_typeable_primitive!(u8);
127derive_typeable_primitive!(u16);
128derive_typeable_primitive!(u32);
129derive_typeable_primitive!(u64);
130derive_typeable_primitive!(u128);
131derive_typeable_primitive!(i8);
132derive_typeable_primitive!(i16);
133derive_typeable_primitive!(i32);
134derive_typeable_primitive!(i64);
135derive_typeable_primitive!(i128);
136derive_typeable_primitive!(f32);
137derive_typeable_primitive!(f64);
138derive_typeable_primitive!(String, string);
139
140impl<T: Typeable, const N: usize> Typeable for [T; N] {
141 fn type_ident() -> TypeId {
142 let mut h = Sha256::new();
143 helper_string_non_ascii(&mut h, "[]");
144 helper_type_args_count(&mut h, 1);
145 helper_usize(&mut h, N);
146 helper_type_ident::<T>(&mut h);
147 TypeId(h.finalize().into())
148 }
149}
150
151impl<T: Typeable> Typeable for Vec<T> {
152 fn type_ident() -> TypeId {
153 let mut h = Sha256::new();
154 helper_type_constructor(&mut h, "Vec");
155 helper_type_args_count(&mut h, 1);
156 helper_type_ident::<T>(&mut h);
157 TypeId(h.finalize().into())
158 }
159}
160
161impl<T: Typeable> Typeable for Option<T> {
162 fn type_ident() -> TypeId {
163 let mut h = Sha256::new();
164 helper_type_constructor(&mut h, "Option");
165 helper_type_args_count(&mut h, 1);
166 helper_type_ident::<T>(&mut h);
167 TypeId(h.finalize().into())
168 }
169}