• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #[derive(Clone)]
2 pub(crate) struct AnyValue {
3     inner: std::sync::Arc<dyn std::any::Any + Send + Sync + 'static>,
4     // While we can extract `TypeId` from `inner`, the debug repr is of a number, so let's track
5     // the type_name in debug builds.
6     id: AnyValueId,
7 }
8 
9 impl AnyValue {
new<V: std::any::Any + Clone + Send + Sync + 'static>(inner: V) -> Self10     pub(crate) fn new<V: std::any::Any + Clone + Send + Sync + 'static>(inner: V) -> Self {
11         let id = AnyValueId::of::<V>();
12         let inner = std::sync::Arc::new(inner);
13         Self { inner, id }
14     }
15 
downcast_ref<T: std::any::Any + Clone + Send + Sync + 'static>( &self, ) -> Option<&T>16     pub(crate) fn downcast_ref<T: std::any::Any + Clone + Send + Sync + 'static>(
17         &self,
18     ) -> Option<&T> {
19         self.inner.downcast_ref::<T>()
20     }
21 
downcast_into<T: std::any::Any + Clone + Send + Sync>(self) -> Result<T, Self>22     pub(crate) fn downcast_into<T: std::any::Any + Clone + Send + Sync>(self) -> Result<T, Self> {
23         let id = self.id;
24         let value =
25             ok!(std::sync::Arc::downcast::<T>(self.inner).map_err(|inner| Self { inner, id }));
26         let value = std::sync::Arc::try_unwrap(value).unwrap_or_else(|arc| (*arc).clone());
27         Ok(value)
28     }
29 
type_id(&self) -> AnyValueId30     pub(crate) fn type_id(&self) -> AnyValueId {
31         self.id
32     }
33 }
34 
35 impl std::fmt::Debug for AnyValue {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error>36     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
37         f.debug_struct("AnyValue").field("inner", &self.id).finish()
38     }
39 }
40 
41 #[derive(Copy, Clone)]
42 pub struct AnyValueId {
43     type_id: std::any::TypeId,
44     #[cfg(debug_assertions)]
45     type_name: &'static str,
46 }
47 
48 impl AnyValueId {
of<A: ?Sized + 'static>() -> Self49     pub(crate) fn of<A: ?Sized + 'static>() -> Self {
50         Self {
51             type_id: std::any::TypeId::of::<A>(),
52             #[cfg(debug_assertions)]
53             type_name: std::any::type_name::<A>(),
54         }
55     }
56 }
57 
58 impl PartialEq for AnyValueId {
eq(&self, other: &Self) -> bool59     fn eq(&self, other: &Self) -> bool {
60         self.type_id == other.type_id
61     }
62 }
63 
64 impl Eq for AnyValueId {}
65 
66 impl PartialOrd for AnyValueId {
partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering>67     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
68         self.type_id.partial_cmp(&other.type_id)
69     }
70 }
71 
72 impl Ord for AnyValueId {
cmp(&self, other: &Self) -> std::cmp::Ordering73     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
74         self.type_id.cmp(&other.type_id)
75     }
76 }
77 
78 impl std::hash::Hash for AnyValueId {
hash<H: std::hash::Hasher>(&self, state: &mut H)79     fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
80         self.type_id.hash(state);
81     }
82 }
83 
84 impl std::fmt::Debug for AnyValueId {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error>85     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
86         #[cfg(not(debug_assertions))]
87         {
88             self.type_id.fmt(f)
89         }
90         #[cfg(debug_assertions)]
91         {
92             f.debug_struct(self.type_name).finish()
93         }
94     }
95 }
96 
97 impl<'a, A: ?Sized + 'static> From<&'a A> for AnyValueId {
from(_: &'a A) -> Self98     fn from(_: &'a A) -> Self {
99         Self::of::<A>()
100     }
101 }
102 
103 #[cfg(test)]
104 mod test {
105     #[test]
106     #[cfg(debug_assertions)]
debug_impl()107     fn debug_impl() {
108         use super::*;
109 
110         assert_eq!(format!("{:?}", AnyValue::new(5)), "AnyValue { inner: i32 }");
111     }
112 }
113