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