temper_core/
mapped.rs

1use super::{i32_to_usize, Error, List, Listed, Result, ToList};
2use indexmap::IndexMap;
3use std::{
4    cell::RefCell,
5    hash::Hash,
6    sync::{Arc, RwLock},
7};
8
9pub trait MappedTrait<K, V>: Sync + Send
10where
11    K: Clone + Sync + Send + Eq + Hash,
12    V: Clone + Sync + Send,
13{
14    fn for_each(&self, action: &dyn Fn(K, V));
15
16    // TODO Receive &K? And more references all throughout be-rust?
17    // TODO &Q where K: Borrow<Q>? See also indexmap::Equivalent.
18    fn get(&self, key: K) -> Result<V>;
19
20    fn get_or(&self, key: K, fallback: V) -> V;
21
22    fn has(&self, key: K) -> bool;
23
24    fn keys(&self) -> Listed<K>;
25
26    fn len(&self) -> i32;
27
28    fn to_list(&self) -> List<(K, V)>;
29
30    fn to_map(&self) -> Map<K, V>;
31
32    fn to_map_builder(&self) -> MapBuilder<K, V>;
33
34    fn values(&self) -> Listed<V>;
35}
36
37pub fn mapped_to_list_with<K, V, T>(
38    mapped: &dyn MappedTrait<K, V>,
39    action: &dyn Fn(K, V) -> T,
40) -> List<T>
41where
42    K: Clone + Sync + Send + Eq + Hash,
43    V: Clone + Sync + Send,
44{
45    let result: RefCell<Vec<T>> = RefCell::new(vec![]);
46    mapped.for_each(&mut |key, value| {
47        result.borrow_mut().push(action(key, value));
48    });
49    result.into_inner().to_list()
50}
51
52#[derive(Clone)]
53pub struct Mapped<K, V>(Arc<dyn MappedTrait<K, V>>);
54
55impl<K, V> Mapped<K, V>
56where
57    K: Clone + Sync + Send + Eq + Hash,
58    V: Clone + Sync + Send,
59{
60    pub fn new(selfish: impl MappedTrait<K, V> + 'static) -> Mapped<K, V> {
61        Mapped(Arc::new(selfish))
62    }
63}
64
65impl<K, V> std::ops::Deref for Mapped<K, V> {
66    type Target = dyn MappedTrait<K, V>;
67    fn deref(&self) -> &Self::Target {
68        &*self.0
69    }
70}
71
72#[derive(Clone)]
73pub struct Map<K, V>(Arc<IndexMap<K, V>>);
74
75impl<K, V> Map<K, V>
76where
77    K: Clone + Eq + Hash,
78    V: Clone,
79{
80    pub fn new(entries: impl ToList<(K, V)>) -> Map<K, V> {
81        let entries = entries.to_list();
82        let mut internal = IndexMap::with_capacity(entries.len());
83        // TODO If we can implement IntoIterator for Listed, this might be nicer.
84        for i in 0..entries.len() {
85            let (key, value) = entries.get(i).unwrap();
86            internal.insert(key.clone(), value.clone());
87        }
88        Map(Arc::new(internal))
89    }
90}
91
92impl<K, V> MappedTrait<K, V> for Map<K, V>
93where
94    K: 'static + Clone + Sync + Send + Eq + Hash,
95    V: 'static + Clone + Sync + Send,
96{
97    fn for_each(&self, action: &dyn Fn(K, V)) {
98        for (key, value) in self.0.iter() {
99            action(key.clone(), value.clone());
100        }
101    }
102
103    fn get(&self, key: K) -> Result<V> {
104        Ok(self.0.get(&key).ok_or_else(Error::new)?.clone())
105    }
106
107    fn get_or(&self, key: K, fallback: V) -> V {
108        self.0.get(&key).cloned().unwrap_or(fallback)
109    }
110
111    fn has(&self, key: K) -> bool {
112        self.0.contains_key(&key)
113    }
114
115    fn keys(&self) -> Listed<K> {
116        Listed::new(self.0.keys().cloned().collect::<Vec<_>>().to_list())
117    }
118
119    fn len(&self) -> i32 {
120        self.0.len().try_into().unwrap()
121    }
122
123    fn to_list(&self) -> List<(K, V)> {
124        self.0
125            .iter()
126            .map(|(key, value)| (key.clone(), value.clone()))
127            .collect::<Vec<_>>()
128            .to_list()
129    }
130
131    fn to_map(&self) -> Map<K, V> {
132        self.clone()
133    }
134
135    fn to_map_builder(&self) -> MapBuilder<K, V> {
136        MapBuilder(RwLock::new((*self.0).clone()).into())
137    }
138
139    fn values(&self) -> Listed<V> {
140        Listed::new(self.0.values().cloned().collect::<Vec<_>>().to_list())
141    }
142}
143
144#[derive(Clone)]
145pub struct MapBuilder<K, V>(Arc<RwLock<IndexMap<K, V>>>);
146
147impl<K, V> MapBuilder<K, V>
148where
149    K: Clone + Eq + Hash,
150    V: Clone,
151{
152    pub fn new() -> MapBuilder<K, V> {
153        MapBuilder(RwLock::new(IndexMap::new()).into())
154    }
155
156    pub fn clear(&self) {
157        self.0.write().unwrap().clear();
158    }
159
160    // Not public!
161    fn get_index(&self, index: i32) -> Option<(K, V)> {
162        let index = i32_to_usize(index).unwrap();
163        let internal = self.0.read().unwrap();
164        let (key, value) = internal.get_index(index)?;
165        Some(((*key).clone(), (*value).clone()))
166    }
167
168    pub fn remove(&self, key: K) -> Result<V> {
169        self.0
170            .write()
171            .unwrap()
172            .shift_remove(&key)
173            .ok_or_else(Error::new)
174    }
175
176    pub fn set(&self, key: K, value: V) {
177        self.0.write().unwrap().insert(key, value);
178    }
179}
180
181impl<K, V> MappedTrait<K, V> for MapBuilder<K, V>
182where
183    K: 'static + Clone + Sync + Send + Eq + Hash,
184    V: 'static + Clone + Sync + Send,
185{
186    fn for_each(&self, action: &dyn Fn(K, V)) {
187        for index in 0..self.len() {
188            let Some((key, value)) = self.get_index(index) else {
189                // This should only happen if the map builder changes during
190                // iteration. For now, just exit early, but we need to decide on
191                // consistent semantics for mutation while looping.
192                return;
193            };
194            action(key, value);
195        }
196    }
197
198    fn get(&self, key: K) -> Result<V> {
199        Ok(self
200            .0
201            .read()
202            .unwrap()
203            .get(&key)
204            .ok_or_else(Error::new)?
205            .clone())
206    }
207
208    fn get_or(&self, key: K, fallback: V) -> V {
209        self.0
210            .read()
211            .unwrap()
212            .get(&key)
213            .cloned()
214            .unwrap_or(fallback)
215    }
216
217    fn has(&self, key: K) -> bool {
218        self.0.read().unwrap().contains_key(&key)
219    }
220
221    fn keys(&self) -> Listed<K> {
222        Listed::new(
223            self.0
224                .read()
225                .unwrap()
226                .keys()
227                .cloned()
228                .collect::<Vec<_>>()
229                .to_list(),
230        )
231    }
232
233    fn len(&self) -> i32 {
234        self.0.read().unwrap().len().try_into().unwrap()
235    }
236
237    fn to_list(&self) -> List<(K, V)> {
238        self.0
239            .read()
240            .unwrap()
241            .iter()
242            .map(|(key, value)| (key.clone(), value.clone()))
243            .collect::<Vec<_>>()
244            .to_list()
245    }
246
247    fn to_map(&self) -> Map<K, V> {
248        Map(self.0.read().unwrap().clone().into())
249    }
250
251    fn to_map_builder(&self) -> MapBuilder<K, V> {
252        MapBuilder(RwLock::new(self.0.read().unwrap().clone()).into())
253    }
254
255    fn values(&self) -> Listed<V> {
256        Listed::new(
257            self.0
258                .read()
259                .unwrap()
260                .values()
261                .cloned()
262                .collect::<Vec<_>>()
263                .to_list(),
264        )
265    }
266}
267
268pub trait Pair<K, V>
269where
270    K: Clone,
271    V: Clone,
272{
273    fn key(&self) -> K;
274    fn value(&self) -> V;
275}
276
277impl<K, V> Pair<K, V> for (K, V)
278where
279    K: Clone,
280    V: Clone,
281{
282    fn key(&self) -> K {
283        self.0.clone()
284    }
285
286    fn value(&self) -> V {
287        self.1.clone()
288    }
289}