lang_extension/any/
mod.rs

1use 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}