Skip to main content

zrx_store/store/adapter/
collections.rs

1// Copyright (c) 2025-2026 Zensical and contributors
2
3// SPDX-License-Identifier: MIT
4// All contributions are certified under the DCO
5
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to
8// deal in the Software without restriction, including without limitation the
9// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10// sell copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12
13// The above copyright notice and this permission notice shall be included in
14// all copies or substantial portions of the Software.
15
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22// IN THE SOFTWARE.
23
24// ----------------------------------------------------------------------------
25
26//! Store implementations for collections.
27
28use std::borrow::Borrow;
29use std::collections::btree_map::{self, BTreeMap};
30use std::collections::hash_map::{self, HashMap};
31use std::hash::BuildHasher;
32
33use crate::store::item::{Key, Value};
34use crate::store::{Store, StoreMut, StoreMutRef};
35
36mod iter;
37
38// ----------------------------------------------------------------------------
39// Trait implementations
40// ----------------------------------------------------------------------------
41
42impl<K, V, S> Store<K, V> for HashMap<K, V, S>
43where
44    K: Key,
45    S: BuildHasher,
46{
47    /// Returns a reference to the value identified by the key.
48    ///
49    /// # Examples
50    ///
51    /// ```
52    /// use std::collections::HashMap;
53    /// use zrx_store::{Store, StoreMut};
54    ///
55    /// // Create store and initial state
56    /// let mut store = HashMap::new();
57    /// store.insert("key", 42);
58    ///
59    /// // Obtain reference to value
60    /// let value = store.get(&"key");
61    /// assert_eq!(value, Some(&42));
62    /// ```
63    #[inline]
64    fn get<Q>(&self, key: &Q) -> Option<&V>
65    where
66        K: Borrow<Q>,
67        Q: Key,
68    {
69        HashMap::get(self, key)
70    }
71
72    /// Returns whether the store contains the key.
73    ///
74    /// # Examples
75    ///
76    /// ```
77    /// use std::collections::HashMap;
78    /// use zrx_store::{Store, StoreMut};
79    ///
80    /// // Create store and initial state
81    /// let mut store = HashMap::new();
82    /// store.insert("key", 42);
83    ///
84    /// // Ensure presence of key
85    /// let check = store.contains_key(&"key");
86    /// assert_eq!(check, true);
87    /// ```
88    #[inline]
89    fn contains_key<Q>(&self, key: &Q) -> bool
90    where
91        K: Borrow<Q>,
92        Q: Key,
93    {
94        HashMap::contains_key(self, key)
95    }
96
97    /// Returns the number of items in the store.
98    #[inline]
99    fn len(&self) -> usize {
100        HashMap::len(self)
101    }
102}
103
104impl<K, V, S> StoreMut<K, V> for HashMap<K, V, S>
105where
106    K: Key,
107    V: Value,
108    S: BuildHasher,
109{
110    /// Inserts the value identified by the key.
111    ///
112    /// # Examples
113    ///
114    /// ```
115    /// use std::collections::HashMap;
116    /// use zrx_store::StoreMut;
117    ///
118    /// // Create store
119    /// let mut store = HashMap::new();
120    ///
121    /// // Insert value
122    /// let value = store.insert("key", 42);
123    /// assert_eq!(value, None);
124    /// ```
125    #[inline]
126    fn insert(&mut self, key: K, value: V) -> Option<V> {
127        match HashMap::entry(self, key) {
128            hash_map::Entry::Vacant(entry) => {
129                entry.insert(value);
130                None
131            }
132            hash_map::Entry::Occupied(mut entry) => {
133                if entry.get() == &value {
134                    None
135                } else {
136                    Some(entry.insert(value))
137                }
138            }
139        }
140    }
141
142    /// Removes the value identified by the key.
143    ///
144    /// # Examples
145    ///
146    /// ```
147    /// use std::collections::HashMap;
148    /// use zrx_store::StoreMut;
149    ///
150    /// // Create store and initial state
151    /// let mut store = HashMap::new();
152    /// store.insert("key", 42);
153    ///
154    /// // Remove and return value
155    /// let value = store.remove(&"key");
156    /// assert_eq!(value, Some(42));
157    /// ```
158    #[inline]
159    fn remove<Q>(&mut self, key: &Q) -> Option<V>
160    where
161        K: Borrow<Q>,
162        Q: Key,
163    {
164        HashMap::remove(self, key)
165    }
166
167    /// Removes the value identified by the key and returns both.
168    ///
169    /// # Examples
170    ///
171    /// ```
172    /// use std::collections::HashMap;
173    /// use zrx_store::StoreMut;
174    ///
175    /// // Create store and initial state
176    /// let mut store = HashMap::new();
177    /// store.insert("key", 42);
178    ///
179    /// // Remove and return entry
180    /// let entry = store.remove_entry(&"key");
181    /// assert_eq!(entry, Some(("key", 42)));
182    /// ```
183    #[inline]
184    fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
185    where
186        K: Borrow<Q>,
187        Q: Key,
188    {
189        HashMap::remove_entry(self, key)
190    }
191
192    /// Clears the store, removing all items.
193    ///
194    /// # Examples
195    ///
196    /// ```
197    /// use std::collections::HashMap;
198    /// use zrx_store::StoreMut;
199    ///
200    /// // Create store and initial state
201    /// let mut store = HashMap::new();
202    /// store.insert("key", 42);
203    ///
204    /// // Clear store
205    /// store.clear();
206    /// assert!(store.is_empty());
207    /// ```
208    #[inline]
209    fn clear(&mut self) {
210        HashMap::clear(self);
211    }
212}
213
214impl<K, V, S> StoreMutRef<K, V> for HashMap<K, V, S>
215where
216    K: Key,
217    S: BuildHasher,
218{
219    /// Returns a mutable reference to the value identified by the key.
220    ///
221    /// # Examples
222    ///
223    /// ```
224    /// use std::collections::HashMap;
225    /// use zrx_store::{StoreMut, StoreMutRef};
226    ///
227    /// // Create store and initial state
228    /// let mut store = HashMap::new();
229    /// store.insert("key", 42);
230    ///
231    /// // Obtain mutable reference to value
232    /// let value = store.get_mut(&"key");
233    /// assert_eq!(value, Some(&mut 42));
234    /// ```
235    #[inline]
236    fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
237    where
238        K: Borrow<Q>,
239        Q: Key,
240    {
241        HashMap::get_mut(self, key)
242    }
243
244    /// Returns a mutable reference to the value or creates the default.
245    ///
246    /// # Examples
247    ///
248    /// ```
249    /// use std::collections::HashMap;
250    /// use zrx_store::StoreMutRef;
251    ///
252    /// // Create store
253    /// let mut store = HashMap::new();
254    /// # let _: HashMap<_, i32> = store;
255    ///
256    /// // Obtain mutable reference to value
257    /// let value = store.get_or_insert_default(&"key");
258    /// assert_eq!(value, &mut 0);
259    /// ```
260    #[inline]
261    fn get_or_insert_default(&mut self, key: &K) -> &mut V
262    where
263        V: Default,
264    {
265        HashMap::entry(self, key.clone()).or_default()
266    }
267}
268
269// ----------------------------------------------------------------------------
270
271impl<K, V> Store<K, V> for BTreeMap<K, V>
272where
273    K: Key,
274{
275    /// Returns a reference to the value identified by the key.
276    ///
277    /// # Examples
278    ///
279    /// ```
280    /// use std::collections::BTreeMap;
281    /// use zrx_store::{Store, StoreMut};
282    ///
283    /// // Create store and initial state
284    /// let mut store = BTreeMap::new();
285    /// store.insert("key", 42);
286    ///
287    /// // Obtain reference to value
288    /// let value = store.get(&"key");
289    /// assert_eq!(value, Some(&42));
290    /// ```
291    #[inline]
292    fn get<Q>(&self, key: &Q) -> Option<&V>
293    where
294        K: Borrow<Q>,
295        Q: Key,
296    {
297        BTreeMap::get(self, key)
298    }
299
300    /// Returns whether the store contains the key.
301    ///
302    /// # Examples
303    ///
304    /// ```
305    /// use std::collections::BTreeMap;
306    /// use zrx_store::{Store, StoreMut};
307    ///
308    /// // Create store and initial state
309    /// let mut store = BTreeMap::new();
310    /// store.insert("key", 42);
311    ///
312    /// // Ensure presence of key
313    /// let check = store.contains_key(&"key");
314    /// assert_eq!(check, true);
315    /// ```
316    #[inline]
317    fn contains_key<Q>(&self, key: &Q) -> bool
318    where
319        K: Borrow<Q>,
320        Q: Key,
321    {
322        BTreeMap::contains_key(self, key)
323    }
324
325    /// Returns the number of items in the store.
326    #[inline]
327    fn len(&self) -> usize {
328        BTreeMap::len(self)
329    }
330}
331
332impl<K, V> StoreMut<K, V> for BTreeMap<K, V>
333where
334    K: Key,
335    V: Value,
336{
337    /// Inserts the value identified by the key.
338    ///
339    /// # Examples
340    ///
341    /// ```
342    /// use std::collections::BTreeMap;
343    /// use zrx_store::StoreMut;
344    ///
345    /// // Create store
346    /// let mut store = BTreeMap::new();
347    ///
348    /// // Insert value
349    /// let value = store.insert("key", 42);
350    /// assert_eq!(value, None);
351    /// ```
352    #[inline]
353    fn insert(&mut self, key: K, value: V) -> Option<V> {
354        match BTreeMap::entry(self, key) {
355            btree_map::Entry::Vacant(entry) => {
356                entry.insert(value);
357                None
358            }
359            btree_map::Entry::Occupied(mut entry) => {
360                if entry.get() == &value {
361                    None
362                } else {
363                    Some(entry.insert(value))
364                }
365            }
366        }
367    }
368
369    /// Removes the value identified by the key.
370    ///
371    /// # Examples
372    ///
373    /// ```
374    /// use std::collections::BTreeMap;
375    /// use zrx_store::StoreMut;
376    ///
377    /// // Create store and initial state
378    /// let mut store = BTreeMap::new();
379    /// store.insert("key", 42);
380    ///
381    /// // Remove and return value
382    /// let value = store.remove(&"key");
383    /// assert_eq!(value, Some(42));
384    /// ```
385    #[inline]
386    fn remove<Q>(&mut self, key: &Q) -> Option<V>
387    where
388        K: Borrow<Q>,
389        Q: Key,
390    {
391        BTreeMap::remove(self, key)
392    }
393
394    /// Removes the value identified by the key and returns both.
395    ///
396    /// # Examples
397    ///
398    /// ```
399    /// use std::collections::BTreeMap;
400    /// use zrx_store::StoreMut;
401    ///
402    /// // Create store and initial state
403    /// let mut store = BTreeMap::new();
404    /// store.insert("key", 42);
405    ///
406    /// // Remove and return entry
407    /// let entry = store.remove_entry(&"key");
408    /// assert_eq!(entry, Some(("key", 42)));
409    /// ```
410    #[inline]
411    fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
412    where
413        K: Borrow<Q>,
414        Q: Key,
415    {
416        BTreeMap::remove_entry(self, key)
417    }
418
419    /// Clears the store, removing all items.
420    ///
421    /// # Examples
422    ///
423    /// ```
424    /// use std::collections::BTreeMap;
425    /// use zrx_store::StoreMut;
426    ///
427    /// // Create store and initial state
428    /// let mut store = BTreeMap::new();
429    /// store.insert("key", 42);
430    ///
431    /// // Clear store
432    /// store.clear();
433    /// assert!(store.is_empty());
434    /// ```
435    #[inline]
436    fn clear(&mut self) {
437        BTreeMap::clear(self);
438    }
439}
440
441impl<K, V> StoreMutRef<K, V> for BTreeMap<K, V>
442where
443    K: Key,
444{
445    /// Returns a mutable reference to the value identified by the key.
446    ///
447    /// # Examples
448    ///
449    /// ```
450    /// use std::collections::BTreeMap;
451    /// use zrx_store::{StoreMut, StoreMutRef};
452    ///
453    /// // Create store and initial state
454    /// let mut store = BTreeMap::new();
455    /// store.insert("key", 42);
456    ///
457    /// // Obtain mutable reference to value
458    /// let value = store.get_mut(&"key");
459    /// assert_eq!(value, Some(&mut 42));
460    /// ```
461    #[inline]
462    fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
463    where
464        K: Borrow<Q>,
465        Q: Key,
466    {
467        BTreeMap::get_mut(self, key)
468    }
469
470    /// Returns a mutable reference to the value or creates the default.
471    ///
472    /// # Examples
473    ///
474    /// ```
475    /// use std::collections::BTreeMap;
476    /// use zrx_store::StoreMutRef;
477    ///
478    /// // Create store
479    /// let mut store = BTreeMap::new();
480    /// # let _: BTreeMap<_, i32> = store;
481    ///
482    /// // Obtain mutable reference to value
483    /// let value = store.get_or_insert_default(&"key");
484    /// assert_eq!(value, &mut 0);
485    /// ```
486    #[inline]
487    fn get_or_insert_default(&mut self, key: &K) -> &mut V
488    where
489        V: Default,
490    {
491        BTreeMap::entry(self, key.clone()).or_default()
492    }
493}