1use std::{any::Any as StdAny, fmt};
9
10#[doc(hidden)]
11pub trait CloneToAny {
12 fn clone_to_any(&self) -> Box<dyn CloneAny>;
14}
15
16impl<T: Any + Clone> CloneToAny for T {
17 #[inline]
18 fn clone_to_any(&self) -> Box<dyn CloneAny> {
19 Box::new(self.clone())
20 }
21}
22
23#[doc(hidden)]
24pub trait CloneToAnySend: Send {
25 fn clone_to_any_send(&self) -> Box<dyn CloneAnySend + Send>;
27}
28
29impl<T: Any + Send + Clone> CloneToAnySend for T {
30 #[inline]
31 fn clone_to_any_send(&self) -> Box<dyn CloneAnySend + Send> {
32 Box::new(self.clone())
33 }
34}
35
36#[doc(hidden)]
37pub trait CloneToAnySync: Sync {
38 fn clone_to_any_sync(&self) -> Box<dyn CloneAnySync + Sync>;
40}
41
42impl<T: Any + Sync + Clone> CloneToAnySync for T {
43 #[inline]
44 fn clone_to_any_sync(&self) -> Box<dyn CloneAnySync + Sync> {
45 Box::new(self.clone())
46 }
47}
48
49#[doc(hidden)]
50pub trait CloneToAnySendSync: Send + Sync {
51 fn clone_to_any_send_sync(&self) -> Box<dyn CloneAnySendSync + Send + Sync>;
53}
54
55impl<T: Any + Send + Sync + Clone> CloneToAnySendSync for T {
56 #[inline]
57 fn clone_to_any_send_sync(&self) -> Box<dyn CloneAnySendSync + Send + Sync> {
58 Box::new(self.clone())
59 }
60}
61
62macro_rules! define {
63 (CloneAny) => {
64 define!(CloneAny remainder);
68 };
69 (CloneAnySend) => {
70 define!(CloneAnySend remainder);
74 };
75 (CloneAnySync) => {
76 define!(CloneAnySync remainder);
80 };
81 (CloneAnySendSync) => {
82 define!(CloneAnySendSync remainder);
86 };
87 (Any) => {
88 define!(Any remainder);
92 };
93 ($t:ident remainder) => {
94 define!($t trait);
105 };
106 (CloneAny trait) => {
107 pub trait CloneAny: Any + CloneToAny { }
109 impl<T: StdAny + Clone> CloneAny for T { }
110 };
111 (CloneAnySend trait) => {
112 pub trait CloneAnySend: Any + CloneToAnySend { }
114 impl<T: StdAny + Send + Clone> CloneAnySend for T { }
115 };
116 (CloneAnySync trait) => {
117 pub trait CloneAnySync: Any + CloneToAnySync { }
119 impl<T: StdAny + Sync + Clone> CloneAnySync for T { }
120 };
121 (CloneAnySendSync trait) => {
122 pub trait CloneAnySendSync: Any + CloneToAnySendSync { }
124 impl<T: StdAny + Send + Sync + Clone> CloneAnySendSync for T { }
125 };
126 (Any trait) => {
127 pub trait Any: StdAny { }
129 impl<T: StdAny> Any for T { }
130 };
131}
132
133macro_rules! impl_clone {
134 ($t:ty, $method:ident) => {
135 impl Clone for Box<$t> {
136 #[inline]
137 fn clone(&self) -> Box<$t> {
138 (**self).$method()
139 }
140 }
141 };
142}
143
144#[allow(missing_docs, clippy::missing_safety_doc)]
146pub trait UncheckedAnyExt: Any {
147 unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T;
148 unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T;
149 unsafe fn downcast_unchecked<T: Any>(self: Box<Self>) -> Box<T>;
150}
151
152#[doc(hidden)]
153pub trait IntoBox<A: ?Sized + UncheckedAnyExt>: Any {
155 fn into_box(self) -> Box<A>;
157}
158
159macro_rules! implement {
160 ($base:ident, $(+ $bounds:ident)*) => {
161 impl fmt::Debug for dyn $base $(+ $bounds)* {
162 #[inline]
163 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
164 f.pad(stringify!($base $(+ $bounds)*))
165 }
166 }
167
168 impl UncheckedAnyExt for dyn $base $(+ $bounds)* {
169 #[inline]
170 unsafe fn downcast_ref_unchecked<T>(&self) -> &T {
171 &*(self as *const Self as *const T)
172 }
173
174 #[inline]
175 unsafe fn downcast_mut_unchecked<T>(&mut self) -> &mut T {
176 &mut *(self as *mut Self as *mut T)
177 }
178
179 #[inline]
180 unsafe fn downcast_unchecked<T>(self: Box<Self>) -> Box<T> {
181 Box::from_raw(Box::into_raw(self) as *mut T)
182 }
183 }
184
185 impl<T: $base $(+ $bounds)*> IntoBox<dyn $base $(+ $bounds)*> for T {
186 #[inline]
187 fn into_box(self) -> Box<dyn $base $(+ $bounds)*> {
188 Box::new(self)
189 }
190 }
191 }
192}
193
194define!(Any);
195implement!(Any,);
196implement!(Any, + Send);
197implement!(Any, + Sync);
198implement!(Any, + Send + Sync);
199implement!(CloneAny,);
200implement!(CloneAnySend, + Send);
201implement!(CloneAnySync, + Sync);
202implement!(CloneAnySendSync, + Send + Sync);
203
204define!(CloneAny);
205define!(CloneAnySend);
206define!(CloneAnySync);
207define!(CloneAnySendSync);
208impl_clone!(dyn CloneAny, clone_to_any);
209impl_clone!((dyn CloneAnySend + Send), clone_to_any_send);
210impl_clone!((dyn CloneAnySync + Sync), clone_to_any_sync);
211impl_clone!((dyn CloneAnySendSync + Send + Sync), clone_to_any_send_sync);