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}