1use std::fmt;
7use std::any::Any as StdAny;
8
9#[doc(hidden)]
10pub trait CloneToAny {
11 fn clone_to_any(&self) -> Box<CloneAny>;
13
14 fn clone_to_any_send(&self) -> Box<CloneAny + Send> where Self: Send;
16
17 fn clone_to_any_sync(&self) -> Box<CloneAny + Sync> where Self: Sync;
19
20 fn clone_to_any_send_sync(&self) -> Box<CloneAny + Send + Sync> where Self: Send + Sync;
22}
23
24impl<T: Any + Clone> CloneToAny for T {
25 #[inline]
26 fn clone_to_any(&self) -> Box<CloneAny> {
27 Box::new(self.clone())
28 }
29
30 #[inline]
31 fn clone_to_any_send(&self) -> Box<CloneAny + Send> where Self: Send {
32 Box::new(self.clone())
33 }
34
35 #[inline]
36 fn clone_to_any_sync(&self) -> Box<CloneAny + Sync> where Self: Sync {
37 Box::new(self.clone())
38 }
39
40 #[inline]
41 fn clone_to_any_send_sync(&self) -> Box<CloneAny + Send + Sync> where Self: Send + Sync {
42 Box::new(self.clone())
43 }
44}
45
46macro_rules! define {
47 (CloneAny) => {
48 define!(CloneAny remainder);
52 };
53 (Any) => {
54 define!(Any remainder);
58 };
59 ($t:ident remainder) => {
60 define!($t trait);
71 };
72 (CloneAny trait) => {
73 pub trait CloneAny: Any + CloneToAny { }
75 impl<T: StdAny + Clone> CloneAny for T { }
76 };
77 (Any trait) => {
78 pub trait Any: StdAny { }
80 impl<T: StdAny> Any for T { }
81 };
82}
83
84macro_rules! impl_clone {
85 ($t:ty, $method:ident) => {
86 impl Clone for Box<$t> {
87 #[inline]
88 fn clone(&self) -> Box<$t> {
89 (**self).$method()
90 }
91 }
92 }
93}
94
95#[allow(missing_docs)] pub trait UncheckedAnyExt: Any {
97 unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T;
98 unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T;
99 unsafe fn downcast_unchecked<T: Any>(self: Box<Self>) -> Box<T>;
100}
101
102#[doc(hidden)]
103pub trait IntoBox<A: ?Sized + UncheckedAnyExt>: Any {
105 fn into_box(self) -> Box<A>;
107}
108
109macro_rules! implement {
110 ($base:ident, $(+ $bounds:ident)*) => {
111 impl fmt::Debug for $base $(+ $bounds)* {
112 #[inline]
113 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
114 f.pad(stringify!($base $(+ $bounds)*))
115 }
116 }
117
118 impl UncheckedAnyExt for $base $(+ $bounds)* {
119 #[inline]
120 unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
121 &*(self as *const Self as *const T)
122 }
123
124 #[inline]
125 unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
126 &mut *(self as *mut Self as *mut T)
127 }
128
129 #[inline]
130 unsafe fn downcast_unchecked<T: 'static>(self: Box<Self>) -> Box<T> {
131 Box::from_raw(Box::into_raw(self) as *mut T)
132 }
133 }
134
135 impl<T: $base $(+ $bounds)*> IntoBox<$base $(+ $bounds)*> for T {
136 #[inline]
137 fn into_box(self) -> Box<$base $(+ $bounds)*> {
138 Box::new(self)
139 }
140 }
141 }
142}
143
144define!(Any);
145implement!(Any,);
146implement!(Any, + Send);
147implement!(Any, + Sync);
148implement!(Any, + Send + Sync);
149implement!(CloneAny,);
150implement!(CloneAny, + Send);
151implement!(CloneAny, + Sync);
152implement!(CloneAny, + Send + Sync);
153
154define!(CloneAny);
155impl_clone!(CloneAny, clone_to_any);
156impl_clone!((CloneAny + Send), clone_to_any_send);
157impl_clone!((CloneAny + Sync), clone_to_any_sync);
158impl_clone!((CloneAny + Send + Sync), clone_to_any_send_sync);