1use std::any::{self, TypeId};
2use std::fmt::{self, Debug};
3use std::hash::{Hash, Hasher};
4
5#[readonly::make]
6#[derive(Clone, Copy)]
7/// [std::any::TypeId] and [std::any::type_name] fused into one struct.
8///
9/// It acts as TypeId when hashed or compared, and it acts as type_name when printed.
10/// Used to improve debuggability of type ids in hashmaps in particular.
11/// ```
12/// # use markdown_it::common::TypeKey;
13/// struct A;
14/// struct B;
15///
16/// let mut set = std::collections::HashSet::new();
17///
18/// set.insert(TypeKey::of::<A>());
19/// set.insert(TypeKey::of::<B>());
20///
21/// assert!(set.contains(&TypeKey::of::<A>()));
22/// dbg!(set);
23/// ```
24pub struct TypeKey {
25 /// type id (read only)
26 pub id: TypeId,
27 /// type name (read only)
28 pub name: &'static str,
29}
30
31impl TypeKey {
32 #[must_use]
33 /// Similar to [TypeId::of](std::any::TypeId::of), returns `TypeKey`
34 /// of the type this generic function has been instantiated with.
35 pub fn of<T: ?Sized + 'static>() -> Self {
36 Self { id: TypeId::of::<T>(), name: any::type_name::<T>() }
37 }
38}
39
40impl Hash for TypeKey {
41 fn hash<H: Hasher>(&self, state: &mut H) {
42 self.id.hash(state);
43 }
44}
45
46impl PartialEq for TypeKey {
47 fn eq(&self, other: &Self) -> bool {
48 self.id == other.id
49 }
50}
51
52impl Eq for TypeKey {}
53
54impl Debug for TypeKey {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 write!(f, "{}", self.name)
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::TypeKey;
63
64 #[test]
65 fn typekey_eq() {
66 struct A;
67 struct B;
68 assert_eq!(TypeKey { id: std::any::TypeId::of::<A>(), name: "foo" },
69 TypeKey { id: std::any::TypeId::of::<A>(), name: "bar" });
70 assert_ne!(TypeKey { id: std::any::TypeId::of::<A>(), name: "foo" },
71 TypeKey { id: std::any::TypeId::of::<B>(), name: "foo" });
72 }
73
74 #[test]
75 fn typekey_of() {
76 struct A;
77 struct B;
78 assert_eq!(TypeKey::of::<A>(), TypeKey::of::<A>());
79 assert_ne!(TypeKey::of::<A>(), TypeKey::of::<B>());
80 }
81}