1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
use std::any::{ Any, type_name }; #[macro_use] mod as_macro; pub use as_macro::*; #[macro_use] mod value; pub use value::*; #[macro_use] mod key; pub use key::*; mod immutable; pub use immutable::*; pub trait AsAny { fn as_any_ref(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; } impl<T: 'static> AsAny for T { fn as_any_ref(&self) -> &dyn Any { self } fn as_any_mut(&mut self) -> &mut dyn Any { self } } pub trait AnyExtension { fn type_name(&self) -> &'static str; fn memory_address(&self) -> usize; fn reference_equals(&self, other: &dyn Any) -> bool; } impl<T: ?Sized> AnyExtension for T { fn type_name(&self) -> &'static str { type_name::<Self>() } fn memory_address(&self) -> usize { self as *const T as *const () as usize } fn reference_equals(&self, other: &dyn Any) -> bool { self.memory_address() == other.memory_address() } } #[cfg(test)] mod tests { use super::*; use std::any::TypeId; #[test] fn as_any() { let d = 1; assert_eq!(d.as_any_ref().type_id(), TypeId::of::<i32>()); let mut d = d; *d.as_any_mut().downcast_mut::<i32>().unwrap() = 2; assert_eq!(2, d); } #[test] fn any_extension() { let a: Box<dyn Any> = Box::new(10); println!("type_name: {}, memory_address: {:?}", a.as_ref().type_name(), a.as_ref().memory_address()); assert_eq!(type_name::<i32>(), 10.type_name()); assert_eq!(type_name::<dyn Any>(), a.as_ref().type_name()); assert_eq!(type_name::<Box<dyn Any>>(), a.type_name()); assert_eq!(a.as_ref().downcast_ref::<i32>().unwrap() as *const i32 as usize, a.as_ref().memory_address()); assert_eq!(&a as *const Box::<dyn Any> as *const () as usize, a.memory_address()); let b: Box<dyn Any> = Box::new(10); assert!(!a.reference_equals(b.as_any_ref())); let x = Box::new(10); assert_eq!(x, x); assert!(x.reference_equals(x.as_any_ref())); let y = Box::new(10); assert_eq!(x, y); assert!(!x.reference_equals(y.as_any_ref())); assert!(!x.as_ref().reference_equals(y.as_ref().as_any_ref())); } }