calimero_primitives/
reflect.rs1use core::any::{type_name, TypeId};
2use core::marker::PhantomData;
3use core::mem::transmute;
4use core::ptr;
5use std::rc::Rc;
6use std::sync::Arc;
7
8fn non_static_type_id<T: ?Sized>() -> TypeId {
13 trait NonStaticAny {
14 fn get_type_id(&self) -> TypeId
15 where
16 Self: 'static;
17 }
18
19 impl<T: ?Sized> NonStaticAny for PhantomData<T> {
20 fn get_type_id(&self) -> TypeId
21 where
22 Self: 'static,
23 {
24 TypeId::of::<T>()
25 }
26 }
27
28 let phantom_data = PhantomData::<T>;
29 NonStaticAny::get_type_id(unsafe {
30 transmute::<&dyn NonStaticAny, &(dyn NonStaticAny + 'static)>(&phantom_data)
31 })
32}
33
34pub trait Reflect {
35 fn type_id(&self) -> TypeId {
36 non_static_type_id::<Self>()
37 }
38
39 fn type_name(&self) -> &'static str {
40 type_name::<Self>()
41 }
42
43 fn as_dyn_ref<'a>(&self) -> &(dyn Reflect + 'a)
44 where
45 Self: 'a;
46
47 fn as_dyn_mut<'a>(&mut self) -> &mut (dyn Reflect + 'a)
48 where
49 Self: 'a;
50
51 fn as_dyn_box<'a>(self: Box<Self>) -> Box<dyn Reflect + 'a>
52 where
53 Self: 'a;
54
55 fn as_dyn_rc<'a>(self: Rc<Self>) -> Rc<dyn Reflect + 'a>
56 where
57 Self: 'a;
58
59 fn as_dyn_arc<'a>(self: Arc<Self>) -> Arc<dyn Reflect + 'a>
60 where
61 Self: 'a;
62}
63
64impl<T> Reflect for T {
65 fn as_dyn_ref<'a>(&self) -> &(dyn Reflect + 'a)
66 where
67 T: 'a,
68 {
69 self
70 }
71
72 fn as_dyn_mut<'a>(&mut self) -> &mut (dyn Reflect + 'a)
73 where
74 T: 'a,
75 {
76 self
77 }
78
79 fn as_dyn_box<'a>(self: Box<Self>) -> Box<dyn Reflect + 'a>
80 where
81 T: 'a,
82 {
83 self
84 }
85
86 fn as_dyn_rc<'a>(self: Rc<Self>) -> Rc<dyn Reflect + 'a>
87 where
88 T: 'a,
89 {
90 self
91 }
92
93 fn as_dyn_arc<'a>(self: Arc<Self>) -> Arc<dyn Reflect + 'a>
94 where
95 T: 'a,
96 {
97 self
98 }
99}
100
101pub trait ReflectExt: Reflect {
102 fn is<T: Reflect + ?Sized>(&self) -> bool {
103 self.type_id() == non_static_type_id::<T>()
104 }
105
106 #[must_use]
107 fn type_id() -> TypeId {
108 non_static_type_id::<Self>()
109 }
110
111 fn downcast_ref<T: Reflect>(&self) -> Option<&T> {
112 if self.is::<T>() {
113 return Some(unsafe { &*ptr::from_ref(self).cast() });
114 }
115
116 None
117 }
118
119 fn downcast_mut<T: Reflect>(&mut self) -> Option<&mut T> {
120 if self.is::<T>() {
121 return Some(unsafe { &mut *ptr::from_mut(self).cast() });
122 }
123
124 None
125 }
126
127 fn downcast_box<T: Reflect>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
128 if (*self).is::<T>() {
129 return Ok(unsafe { Box::from_raw(Box::into_raw(self).cast()) });
130 }
131
132 Err(self)
133 }
134
135 fn downcast_rc<T: Reflect>(self: Rc<Self>) -> Result<Rc<T>, Rc<Self>> {
136 if (*self).is::<T>() {
137 return Ok(unsafe { Rc::from_raw(Rc::into_raw(self).cast()) });
138 }
139
140 Err(self)
141 }
142
143 fn downcast_arc<T: Reflect>(self: Arc<Self>) -> Result<Arc<T>, Arc<Self>> {
144 if (*self).is::<T>() {
145 return Ok(unsafe { Arc::from_raw(Arc::into_raw(self).cast()) });
146 }
147
148 Err(self)
149 }
150}
151
152impl<T: Reflect + ?Sized> ReflectExt for T {}