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}