Skip to main content

zrx_store/store/adapter/
slab.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 [`Slab`].
27
28use slab::Slab;
29use std::borrow::Borrow;
30use std::mem;
31
32use crate::store::item::{Key, Value};
33use crate::store::{Store, StoreMut, StoreMutRef};
34
35mod iter;
36
37pub use iter::{Iter, IterMut, Keys, Values};
38
39// ----------------------------------------------------------------------------
40// Trait implementations
41// ----------------------------------------------------------------------------
42
43impl<K, V> Store<K, V> for Slab<(K, V)> {
44    /// Returns a reference to the value identified by the key.
45    ///
46    /// # Examples
47    ///
48    /// ```
49    /// use slab::Slab;
50    /// use zrx_store::{Store, StoreMut};
51    ///
52    /// // Create store and initial state
53    /// let mut store = Slab::new();
54    /// StoreMut::insert(&mut store, "key", 42);
55    ///
56    /// // Obtain reference to value
57    /// let value = Store::get(&store, &"key");
58    /// assert_eq!(value, Some(&42));
59    /// ```
60    #[inline]
61    fn get<Q>(&self, key: &Q) -> Option<&V>
62    where
63        K: Borrow<Q>,
64        Q: Key,
65    {
66        Slab::iter(self).find_map(|(_, (check, value))| {
67            (check.borrow() == key).then_some(value)
68        })
69    }
70
71    /// Returns whether the store contains the key.
72    ///
73    /// # Examples
74    ///
75    /// ```
76    /// use slab::Slab;
77    /// use zrx_store::{Store, StoreMut};
78    ///
79    /// // Create store and initial state
80    /// let mut store = Slab::new();
81    /// StoreMut::insert(&mut store, "key", 42);
82    ///
83    /// // Ensure presence of key
84    /// let check = Store::contains_key(&store, &"key");
85    /// assert_eq!(check, true);
86    /// ```
87    #[inline]
88    fn contains_key<Q>(&self, key: &Q) -> bool
89    where
90        K: Borrow<Q>,
91        Q: Key,
92    {
93        Slab::iter(self).any(|(_, (check, _))| check.borrow() == key)
94    }
95
96    /// Returns the number of items in the store.
97    #[inline]
98    fn len(&self) -> usize {
99        Slab::len(self)
100    }
101}
102
103impl<K, V> StoreMut<K, V> for Slab<(K, V)>
104where
105    K: Key,
106    V: Value,
107{
108    /// Inserts the value identified by the key.
109    ///
110    /// # Examples
111    ///
112    /// ```
113    /// use slab::Slab;
114    /// use zrx_store::StoreMut;
115    ///
116    /// // Create store
117    /// let mut store = Slab::new();
118    ///
119    /// // Insert value
120    /// let value = StoreMut::insert(&mut store, "key", 42);
121    /// assert_eq!(value, None);
122    /// ```
123    #[inline]
124    fn insert(&mut self, key: K, value: V) -> Option<V> {
125        let opt = Slab::iter_mut(self).find(|(_, (check, _))| check == &key);
126        if let Some((_, (_, prior))) = opt {
127            (prior != &value).then(|| mem::replace(prior, value))
128        } else {
129            self.insert((key, value));
130            None
131        }
132    }
133
134    /// Removes the value identified by the key.
135    ///
136    /// # Examples
137    ///
138    /// ```
139    /// use slab::Slab;
140    /// use zrx_store::StoreMut;
141    ///
142    /// // Create store and initial state
143    /// let mut store = Slab::new();
144    /// StoreMut::insert(&mut store, "key", 42);
145    ///
146    /// // Remove and return value
147    /// let value = StoreMut::remove(&mut store, &"key");
148    /// assert_eq!(value, Some(42));
149    /// ```
150    #[inline]
151    fn remove<Q>(&mut self, key: &Q) -> Option<V>
152    where
153        K: Borrow<Q>,
154        Q: Key,
155    {
156        self.remove_entry(key).map(|(_, value)| value)
157    }
158
159    /// Removes the value identified by the key and returns both.
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// use slab::Slab;
165    /// use zrx_store::StoreMut;
166    ///
167    /// // Create store and initial state
168    /// let mut store = Slab::new();
169    /// StoreMut::insert(&mut store, "key", 42);
170    ///
171    /// // Remove and return entry
172    /// let entry = StoreMut::remove_entry(&mut store, &"key");
173    /// assert_eq!(entry, Some(("key", 42)));
174    /// ```
175    #[inline]
176    fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
177    where
178        K: Borrow<Q>,
179        Q: Key,
180    {
181        Slab::iter(self)
182            .position(|(_, (check, _))| check.borrow() == key)
183            .map(|index| self.remove(index))
184    }
185
186    /// Clears the store, removing all items.
187    ///
188    /// # Examples
189    ///
190    /// ```
191    /// use slab::Slab;
192    /// use zrx_store::StoreMut;
193    ///
194    /// // Create store and initial state
195    /// let mut store = Slab::new();
196    /// StoreMut::insert(&mut store, "key", 42);
197    ///
198    /// // Clear store
199    /// StoreMut::clear(&mut store);
200    /// assert!(store.is_empty());
201    /// ```
202    #[inline]
203    fn clear(&mut self) {
204        Slab::clear(self);
205    }
206}
207
208impl<K, V> StoreMutRef<K, V> for Slab<(K, V)>
209where
210    K: Key,
211{
212    /// Returns a mutable reference to the value identified by the key.
213    ///
214    /// # Examples
215    ///
216    /// ```
217    /// use slab::Slab;
218    /// use zrx_store::{StoreMut, StoreMutRef};
219    ///
220    /// // Create store and initial state
221    /// let mut store = Slab::new();
222    /// StoreMut::insert(&mut store, "key", 42);
223    ///
224    /// // Obtain mutable reference to value
225    /// let mut value = StoreMutRef::get_mut(&mut store, &"key");
226    /// assert_eq!(value, Some(&mut 42));
227    /// ```
228    #[inline]
229    fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
230    where
231        K: Borrow<Q>,
232        Q: Key,
233    {
234        Slab::iter_mut(self).find_map(|(_, (check, value))| {
235            ((*check).borrow() == key).then_some(value)
236        })
237    }
238
239    /// Returns a mutable reference to the value or creates the default.
240    ///
241    /// # Examples
242    ///
243    /// ```
244    /// use slab::Slab;
245    /// use zrx_store::StoreMutRef;
246    ///
247    /// // Create store
248    /// let mut store = Slab::new();
249    /// # let _: Slab<(_, i32)> = store;
250    ///
251    /// // Obtain mutable reference to value
252    /// let value = StoreMutRef::get_or_insert_default(&mut store, &"key");
253    /// assert_eq!(value, &mut 0);
254    /// ```
255    #[inline]
256    fn get_or_insert_default(&mut self, key: &K) -> &mut V
257    where
258        V: Default,
259    {
260        let index = Slab::iter(self)
261            .position(|(_, (check, _))| check == key)
262            .unwrap_or_else(|| Slab::insert(self, (key.clone(), V::default())));
263
264        // Return mutable reference
265        &mut self[index].1
266    }
267}