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 fn type_id() -> TypeId {
107 non_static_type_id::<Self>()
108 }
109
110 fn downcast_ref<T: Reflect>(&self) -> Option<&T> {
111 if self.is::<T>() {
112 return Some(unsafe { &*ptr::from_ref(self).cast() });
113 }
114
115 None
116 }
117
118 fn downcast_mut<T: Reflect>(&mut self) -> Option<&mut T> {
119 if self.is::<T>() {
120 return Some(unsafe { &mut *ptr::from_mut(self).cast() });
121 }
122
123 None
124 }
125
126 fn downcast_box<T: Reflect>(self: Box<Self>) -> Result<Box<T>, Box<Self>> {
127 if (&*self).is::<T>() {
128 return Ok(unsafe { Box::from_raw(Box::into_raw(self).cast()) });
129 }
130
131 Err(self)
132 }
133
134 fn downcast_rc<T: Reflect>(self: Rc<Self>) -> Result<Rc<T>, Rc<Self>> {
135 if (&*self).is::<T>() {
136 return Ok(unsafe { Rc::from_raw(Rc::into_raw(self).cast()) });
137 }
138
139 Err(self)
140 }
141
142 fn downcast_arc<T: Reflect>(self: Arc<Self>) -> Result<Arc<T>, Arc<Self>> {
143 if (&*self).is::<T>() {
144 return Ok(unsafe { Arc::from_raw(Arc::into_raw(self).cast()) });
145 }
146
147 Err(self)
148 }
149}
150
151impl<T: Reflect + ?Sized> ReflectExt for T {}