lang_extension/any/
immutable.rs1use 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}