lang_extension/any/
immutable.rs

1use std::sync::Arc;
2
3use super::*;
4
5#[derive(PartialEq, Debug, Clone)]
6pub struct ImmutableValue {
7    value: Arc<Box<dyn Value>>,
8}
9
10impl ImmutableValue {
11    pub fn new<T: Value>(value: T) -> ImmutableValue {
12        Self::wrap(Value::to_boxed(value))
13    }
14
15    pub fn wrap(value: Box<dyn Value>) -> Self {
16        ImmutableValue {
17            value: Arc::new(value),
18        }
19    }
20
21    pub fn raw_boxed(&self) -> Box<dyn Value> {
22        self.value.as_ref().clone()
23    }
24}
25
26unsafe impl Send for ImmutableValue {}
27
28unsafe impl Sync for ImmutableValue {}
29
30#[derive(Hash, PartialEq, Eq, Debug, Clone)]
31pub struct ImmutableKey {
32    key: Arc<Box<dyn Key>>,
33}
34
35impl ImmutableKey {
36    pub fn new<T: Key>(value: T) -> ImmutableKey {
37        Self::wrap(Key::to_boxed(value))
38    }
39
40    pub fn wrap(value: Box<dyn Key>) -> Self {
41        ImmutableKey {
42            key: Arc::new(value),
43        }
44    }
45
46    pub fn raw_boxed(&self) -> Box<dyn Key> {
47        self.key.as_ref().clone()
48    }
49}
50
51unsafe impl Send for ImmutableKey {}
52
53unsafe impl Sync for ImmutableKey {}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58    use std::collections::hash_map::DefaultHasher;
59    use std::hash::{Hash, Hasher};
60    use std::thread;
61
62    #[test]
63    fn immutable_value() {
64        assert_eq!(ImmutableValue::new("value"), ImmutableValue::new("value"));
65        assert_ne!(ImmutableValue::new("value"), ImmutableValue::new("value2"));
66
67        println!("{:?}", ImmutableValue::new("value"));
68
69        let v = ImmutableValue::new("value");
70        assert_eq!(&v, &v.clone());
71
72        let b: Box<dyn Value> = Box::new("value");
73        assert_eq!(
74            ImmutableValue::new("value"),
75            ImmutableValue::wrap(b.clone())
76        );
77
78        assert_eq!(&b, &v.raw_boxed());
79
80        let clone = v.clone();
81        let handle = thread::spawn(move || {
82            println!("data: {:?}", clone);
83        });
84        handle.join().unwrap();
85    }
86
87    #[test]
88    fn immutable_key() {
89        assert_eq!(ImmutableKey::new("key"), ImmutableKey::new("key"));
90        assert_ne!(ImmutableKey::new("key"), ImmutableKey::new("key2"));
91
92        println!("{:?}", ImmutableKey::new("key"));
93
94        let k = ImmutableKey::new("key");
95        assert_eq!(&k, &k.clone());
96
97        let b: Box<dyn Key> = Box::new("key");
98        assert_eq!(ImmutableKey::new("key"), ImmutableKey::wrap(b.clone()));
99
100        assert_eq!(&b, &k.raw_boxed());
101
102        let clone = k.clone();
103        let handle = thread::spawn(move || {
104            println!("data: {:?}", clone);
105        });
106        handle.join().unwrap();
107
108        let mut hasher = DefaultHasher::new();
109        k.hash(&mut hasher);
110        let _ = hasher.finish();
111    }
112}