d9080406cafa8c6808d20afcb5ebe9406d6cec83
[anymap] / src / raw / any.rs
1 use std::fmt;
2 use std::any::Any as StdAny;
3
4 #[cfg(feature = "clone")]
5 #[doc(hidden)]
6 pub trait CloneToAny {
7 /// Clone `self` into a new `Box<Any>` object.
8 fn clone_to_any(&self) -> Box<Any>;
9 }
10
11 #[cfg(feature = "clone")]
12 impl<T: Any + Clone> CloneToAny for T {
13 fn clone_to_any(&self) -> Box<Any> {
14 Box::new(self.clone())
15 }
16 }
17
18 macro_rules! define_any {
19 (#[$m:meta] $t:item $i:item) => {
20 /// A type to emulate dynamic typing.
21 ///
22 /// Every suitable type with no non-`'static` references implements `Any`. See the
23 /// [`std::any` documentation](https://doc.rust-lang.org/std/any/index.html) for more
24 /// details on `Any` in general.
25 ///
26 /// This trait is not `std::any::Any` but rather a type extending that for this library’s
27 /// purposes; most specifically, there are a couple of Cargo features that can be enabled
28 /// which will alter the constraints of what comprises a suitable type:
29 ///
30 /// <table>
31 /// <thead>
32 /// <tr>
33 /// <th title="The name of the Cargo feature to enable">Feature name</th>
34 /// <th title="If a type doesn’t satisfy these bounds, it won’t implement Any">Additional bounds</th>
35 /// <th title="Were these docs built with this feature enabled?">Enabled in these docs?</th>
36 /// </tr>
37 /// </thead>
38 /// <tbody>
39 /// <tr>
40 /// <th><code>clone</code></th>
41 /// <td><code><a class=trait title=core::clone::Clone
42 /// href=http://doc.rust-lang.org/std/clone/trait.Clone.html
43 /// >Clone</a></code></td>
44 #[cfg_attr(feature = "clone", doc = " <td>Yes</td>")]
45 #[cfg_attr(not(feature = "clone"), doc = " <td>No</td>")]
46 /// </tr>
47 /// <tr>
48 /// <th><code>concurrent</code></th>
49 /// <td><code><a class=trait title=core::marker::Send
50 /// href=http://doc.rust-lang.org/std/marker/trait.Send.html
51 /// >Send</a> + <a class=trait title=core::marker::Sync
52 /// href=http://doc.rust-lang.org/std/marker/trait.Sync.html
53 /// >Sync</a></code></td>
54 #[cfg_attr(feature = "concurrent", doc = " <td>Yes</td>")]
55 #[cfg_attr(not(feature = "concurrent"), doc = " <td>No</td>")]
56 /// </tr>
57 /// </tbody>
58 /// </table>
59 #[$m] $t
60 #[$m] $i
61 }
62 }
63
64 define_any! {
65 #[cfg(all(not(feature = "clone"), not(feature = "concurrent")))]
66 pub trait Any: StdAny { }
67 impl<T: StdAny> Any for T { }
68 }
69
70 define_any! {
71 #[cfg(all(feature = "clone", not(feature = "concurrent")))]
72 pub trait Any: StdAny + CloneToAny { }
73 impl<T: StdAny + Clone> Any for T { }
74 }
75
76 define_any! {
77 #[cfg(all(not(feature = "clone"), feature = "concurrent"))]
78 pub trait Any: StdAny + Send + Sync { }
79 impl<T: StdAny + Send + Sync> Any for T { }
80 }
81
82 define_any! {
83 #[cfg(all(feature = "clone", feature = "concurrent"))]
84 pub trait Any: StdAny + CloneToAny + Send + Sync { }
85 impl<T: StdAny + Clone + Send + Sync> Any for T { }
86 }
87
88 #[cfg(feature = "clone")]
89 impl Clone for Box<Any> {
90 fn clone(&self) -> Box<Any> {
91 (**self).clone_to_any()
92 }
93 }
94
95 impl<'a> fmt::Debug for &'a Any {
96 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97 f.pad("&Any")
98 }
99 }
100
101 impl<'a> fmt::Debug for Box<Any> {
102 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103 f.pad("Box<Any>")
104 }
105 }