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 Some(self.cmp(other)) 69 } 70 } 71 72 impl PartialEq<std::any::TypeId> for AnyValueId { eq(&self, other: &std::any::TypeId) -> bool73 fn eq(&self, other: &std::any::TypeId) -> bool { 74 self.type_id == *other 75 } 76 } 77 78 impl Ord for AnyValueId { cmp(&self, other: &Self) -> std::cmp::Ordering79 fn cmp(&self, other: &Self) -> std::cmp::Ordering { 80 self.type_id.cmp(&other.type_id) 81 } 82 } 83 84 impl std::hash::Hash for AnyValueId { hash<H: std::hash::Hasher>(&self, state: &mut H)85 fn hash<H: std::hash::Hasher>(&self, state: &mut H) { 86 self.type_id.hash(state); 87 } 88 } 89 90 impl std::fmt::Debug for AnyValueId { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error>91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { 92 #[cfg(not(debug_assertions))] 93 { 94 self.type_id.fmt(f) 95 } 96 #[cfg(debug_assertions)] 97 { 98 f.debug_struct(self.type_name).finish() 99 } 100 } 101 } 102 103 impl<'a, A: ?Sized + 'static> From<&'a A> for AnyValueId { from(_: &'a A) -> Self104 fn from(_: &'a A) -> Self { 105 Self::of::<A>() 106 } 107 } 108 109 #[cfg(test)] 110 mod test { 111 #[test] 112 #[cfg(debug_assertions)] debug_impl()113 fn debug_impl() { 114 use super::*; 115 116 assert_eq!(format!("{:?}", AnyValue::new(5)), "AnyValue { inner: i32 }"); 117 } 118 119 #[test] eq_to_type_id()120 fn eq_to_type_id() { 121 use super::*; 122 123 let any_value_id = AnyValueId::of::<i32>(); 124 let type_id = std::any::TypeId::of::<i32>(); 125 assert_eq!(any_value_id, type_id); 126 } 127 } 128