1use crate::types::MetaCallValue;
2use std::any::Any;
3
4pub trait MetaCallDowncast: Any {
5 fn into_any(self: Box<Self>) -> Box<dyn Any>;
6 fn as_any(&self) -> &dyn Any;
7 fn as_any_mut(&mut self) -> &mut dyn Any;
8}
9impl<T: Any> MetaCallDowncast for T {
10 fn into_any(self: Box<Self>) -> Box<dyn Any> {
11 self
12 }
13 fn as_any(&self) -> &dyn Any {
14 self
15 }
16 fn as_any_mut(&mut self) -> &mut dyn Any {
17 self
18 }
19}
20impl dyn MetaCallValue {
21 pub fn is<T: MetaCallValue>(&self) -> bool {
23 MetaCallDowncast::as_any(self).is::<T>()
24 }
25
26 pub fn downcast<T: MetaCallValue>(self: Box<Self>) -> Result<T, Box<Self>> {
28 if self.is::<T>() {
29 Ok(*MetaCallDowncast::into_any(self).downcast::<T>().unwrap())
30 } else {
31 Err(self)
32 }
33 }
34
35 pub fn downcast_ref<T: MetaCallValue>(&self) -> Option<&T> {
37 MetaCallDowncast::as_any(self).downcast_ref::<T>()
38 }
39
40 pub fn downcast_mut<T: MetaCallValue>(&mut self) -> Option<&mut T> {
42 MetaCallDowncast::as_any_mut(self).downcast_mut::<T>()
43 }
44}
45
46pub trait MetaCallSealed {}
47impl<T: Clone> MetaCallSealed for T {}
48impl MetaCallSealed for str {}
49impl<T: Clone> MetaCallSealed for [T] {}
50
51pub fn clone_box<T>(t: &T) -> Box<T>
52where
53 T: ?Sized + MetaCallClone,
54{
55 unsafe {
56 let mut fat_ptr = t as *const T;
57 let data_ptr = &mut fat_ptr as *mut *const T as *mut *mut ();
58
59 assert_eq!(*data_ptr as *const (), t as *const T as *const ());
60
61 *data_ptr = <T as MetaCallClone>::clone_box(t);
62
63 Box::from_raw(fat_ptr as *mut T)
64 }
65}
66
67pub trait MetaCallClone: MetaCallSealed {
68 fn clone_box(&self) -> *mut ();
69}
70impl<T> MetaCallClone for T
71where
72 T: Clone,
73{
74 fn clone_box(&self) -> *mut () {
75 Box::<T>::into_raw(Box::new(self.clone())) as *mut ()
76 }
77}
78
79impl MetaCallClone for str {
80 fn clone_box(&self) -> *mut () {
81 Box::<str>::into_raw(Box::from(self)) as *mut ()
82 }
83}
84impl<T> MetaCallClone for [T]
85where
86 T: Clone,
87{
88 fn clone_box(&self) -> *mut () {
89 Box::<[T]>::into_raw(self.iter().cloned().collect()) as *mut ()
90 }
91}
92impl Clone for Box<dyn MetaCallValue + '_> {
93 fn clone(&self) -> Self {
94 clone_box(&**self)
95 }
96}
97impl Clone for Box<dyn MetaCallValue + Send + '_> {
98 fn clone(&self) -> Self {
99 clone_box(&**self)
100 }
101}
102impl Clone for Box<dyn MetaCallValue + Sync + '_> {
103 fn clone(&self) -> Self {
104 clone_box(&**self)
105 }
106}
107impl Clone for Box<dyn MetaCallValue + Send + Sync + '_> {
108 fn clone(&self) -> Self {
109 clone_box(&**self)
110 }
111}