Skip to main content

zrx_store/
store.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 traits.
27
28use std::borrow::Borrow;
29use std::ops::RangeBounds;
30
31pub mod adapter;
32pub mod collection;
33pub mod comparator;
34pub mod decorator;
35pub mod item;
36
37use comparator::Comparator;
38use item::{Key, Value};
39
40// ----------------------------------------------------------------------------
41// Traits
42// ----------------------------------------------------------------------------
43
44/// Immutable store.
45///
46/// This trait defines the required methods for an immutable key-value store,
47/// abstracting over implementations like [`HashMap`][] and [`BTreeMap`][]. It
48/// forms the foundation for a set of further traits that define complementary
49/// capabilities for stores, like [`StoreMut`] and [`StoreIterable`].
50///
51/// There are several of those traits, all of which can be composed in trait
52/// bounds to require specific store capabilities. These are:
53///
54/// - [`StoreMut`]: Mutable store.
55/// - [`StoreMutRef`]: Mutable store that can return mutable references.
56/// - [`StoreIterable`]: Immutable store that is iterable.
57/// - [`StoreIterableMut`]: Mutable store that is iterable.
58/// - [`StoreKeys`]: Immutable store that is iterable over its keys.
59/// - [`StoreValues`]: Immutable store that is iterable over its values.
60/// - [`StoreRange`]: Immutable store that is iterable over a range.
61///
62/// For insertion and removal semantics, it's important to understand that
63/// stores compare each value with the prior value before mutation:
64///
65/// - [`StoreMut::insert`] returns the prior value if existent and different.
66/// - [`StoreMut::remove`] returns the prior value if existent.
67///
68/// This trait is implemented for [`HashMap`][] and [`BTreeMap`][], as well as
69/// all of the store [`decorators`][] that allow to wrap stores with additional
70/// capabilities. Note that stores are not thread-safe, so they can't be shared
71/// among worker threads.
72///
73/// All methods deliberately have [`Infallible`] signatures, as stores must be
74/// fast and reliable, and should never fail under normal circumstances. Stores
75/// should not need to serialize data, write to the filesystem, or send data
76/// over the network. They should only have in-memory representations.
77///
78/// [`decorators`]: crate::store::decorator
79/// [`BTreeMap`]: std::collections::BTreeMap
80/// [`HashMap`]: std::collections::HashMap
81/// [`Infallible`]: std::convert::Infallible
82///
83/// # Examples
84///
85/// ```
86/// use std::collections::HashMap;
87/// use zrx_store::StoreMut;
88///
89/// // Create store and initial state
90/// let mut store = HashMap::new();
91/// store.insert("key", 42);
92///
93/// // Obtain reference to value
94/// let value = store.get(&"key");
95/// assert_eq!(value, Some(&42));
96/// ```
97pub trait Store<K, V> {
98    /// Returns a reference to the value identified by the key.
99    fn get<Q>(&self, key: &Q) -> Option<&V>
100    where
101        K: Borrow<Q>,
102        Q: Key;
103
104    /// Returns whether the store contains the key.
105    fn contains_key<Q>(&self, key: &Q) -> bool
106    where
107        K: Borrow<Q>,
108        Q: Key;
109
110    /// Returns the number of items in the store.
111    fn len(&self) -> usize;
112
113    /// Returns whether the store is empty.
114    #[inline]
115    fn is_empty(&self) -> bool {
116        self.len() == 0
117    }
118}
119
120/// Mutable store.
121///
122/// This trait extends [`Store`], requiring further additional mutable methods
123/// which can be used to alter the store, like inserting and removing items.
124///
125/// # Examples
126///
127/// ```
128/// use std::collections::HashMap;
129/// use zrx_store::StoreMut;
130///
131/// // Create store and initial state
132/// let mut store = HashMap::new();
133/// store.insert("key", 42);
134///
135/// // Remove value from store
136/// let value = store.remove(&"key");
137/// assert_eq!(value, Some(42));
138/// ```
139pub trait StoreMut<K, V>: Store<K, V> {
140    /// Inserts the value identified by the key.
141    fn insert(&mut self, key: K, value: V) -> Option<V>;
142
143    /// Removes the value identified by the key.
144    fn remove<Q>(&mut self, key: &Q) -> Option<V>
145    where
146        K: Borrow<Q>,
147        Q: Key;
148
149    /// Removes the value identified by the key and returns both.
150    fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
151    where
152        K: Borrow<Q>,
153        Q: Key;
154
155    /// Clears the store, removing all items.
156    fn clear(&mut self);
157}
158
159/// Mutable store that can return mutable references.
160///
161/// This trait extends [`StoreMut`], adding the possibility to obtain mutable
162/// references as a requirement, so values can be mutated in-place.
163///
164/// # Examples
165///
166/// ```
167/// use std::collections::HashMap;
168/// use zrx_store::{StoreMut, StoreMutRef};
169///
170/// // Create store and initial state
171/// let mut store = HashMap::new();
172/// store.insert("key", 42);
173///
174/// // Obtain mutable reference to value
175/// let value = store.get_mut(&"key");
176/// assert_eq!(value, Some(&mut 42));
177/// ```
178pub trait StoreMutRef<K, V>: Store<K, V> {
179    /// Returns a mutable reference to the value identified by the key.
180    fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
181    where
182        K: Borrow<Q>,
183        Q: Key;
184
185    /// Returns a mutable reference to the value or creates the default.
186    fn get_or_insert_default(&mut self, key: &K) -> &mut V
187    where
188        V: Default;
189}
190
191/// Immutable store that is iterable.
192///
193/// This trait extends [`Store`], adding iteration capabilities as a further
194/// requirement, so a store can enumerate its items.
195///
196/// # Examples
197///
198/// ```
199/// use std::collections::HashMap;
200/// use zrx_store::{StoreIterable, StoreMut};
201///
202/// // Create store and initial state
203/// let mut store = HashMap::new();
204/// store.insert("key", 42);
205///
206/// // Create iterator over the store
207/// for (key, value) in store.iter() {
208///     println!("{key}: {value}");
209/// }
210/// ```
211pub trait StoreIterable<K, V>: Store<K, V>
212where
213    K: Key,
214    V: Value,
215{
216    type Iter<'a>: Iterator<Item = (&'a K, &'a V)>
217    where
218        Self: 'a;
219
220    /// Creates an iterator over the items of the store.
221    fn iter(&self) -> Self::Iter<'_>;
222}
223
224/// Mutable store that is iterable.
225///
226/// This trait extends [`StoreMut`], adding mutable iteration capabilities as a
227/// requirement, so a store can enumerate its items mutably.
228///
229/// # Examples
230///
231/// ```
232/// use std::collections::HashMap;
233/// use zrx_store::{StoreIterableMut, StoreMut};
234///
235/// // Create store and initial state
236/// let mut store = HashMap::new();
237/// store.insert("key", 42);
238///
239/// // Create iterator over the store
240/// for (key, value) in store.iter_mut() {
241///     println!("{key}: {value}");
242/// }
243/// ```
244pub trait StoreIterableMut<K, V>: StoreMut<K, V>
245where
246    K: Key,
247    V: Value,
248{
249    type IterMut<'a>: Iterator<Item = (&'a K, &'a mut V)>
250    where
251        Self: 'a;
252
253    /// Creates a mutable iterator over the items of the store.
254    fn iter_mut(&mut self) -> Self::IterMut<'_>;
255}
256
257/// Immutable store that is iterable over its keys.
258///
259/// This trait extends [`Store`], adding key iteration capabilities as a
260/// requirement, so a store can enumerate its keys.
261///
262/// # Examples
263///
264/// ```
265/// use std::collections::HashMap;
266/// use zrx_store::{StoreKeys, StoreMut};
267///
268/// // Create store and initial state
269/// let mut store = HashMap::new();
270/// store.insert("key", 42);
271///
272/// // Create iterator over the store
273/// for key in store.keys() {
274///     println!("{key}");
275/// }
276/// ```
277pub trait StoreKeys<K, V>: Store<K, V>
278where
279    K: Key,
280{
281    type Keys<'a>: Iterator<Item = &'a K>
282    where
283        Self: 'a;
284
285    /// Creates an iterator over the keys of the store.
286    fn keys(&self) -> Self::Keys<'_>;
287}
288
289/// Immutable store that is iterable over its values.
290///
291/// This trait extends [`Store`], adding value iteration capabilities as a
292/// requirement, so a store can enumerate its values.
293///
294/// # Examples
295///
296/// ```
297/// use std::collections::HashMap;
298/// use zrx_store::{StoreMut, StoreValues};
299///
300/// // Create store and initial state
301/// let mut store = HashMap::new();
302/// store.insert("key", 42);
303///
304/// // Create iterator over the store
305/// for value in store.values() {
306///     println!("{value}");
307/// }
308/// ```
309pub trait StoreValues<K, V>: Store<K, V>
310where
311    K: Key,
312    V: Value,
313{
314    type Values<'a>: Iterator<Item = &'a V>
315    where
316        Self: 'a;
317
318    /// Creates an iterator over the values of the store.
319    fn values(&self) -> Self::Values<'_>;
320}
321
322/// Immutable store that is iterable over a range.
323///
324/// This trait extends [`Store`], adding iteration capabilities as a further
325/// requirement, so a store can enumerate its items over a given range.
326///
327/// # Examples
328///
329/// ```
330/// use std::collections::BTreeMap;
331/// use zrx_store::{StoreMut, StoreRange};
332///
333/// // Create store and initial state
334/// let mut store = BTreeMap::new();
335/// store.insert("a", 42);
336/// store.insert("b", 84);
337///
338/// // Create iterator over the store
339/// for (key, value) in store.range("b"..) {
340///     println!("{key}: {value}");
341/// }
342/// ```
343pub trait StoreRange<K, V>: Store<K, V>
344where
345    K: Key,
346    V: Value,
347{
348    type Range<'a>: Iterator<Item = (&'a K, &'a V)>
349    where
350        Self: 'a;
351
352    /// Creates an iterator over a range of items of the store.
353    fn range<R>(&self, range: R) -> Self::Range<'_>
354    where
355        R: RangeBounds<K>;
356}
357
358// ----------------------------------------------------------------------------
359
360/// Creates a store with a comparator.
361///
362/// This trait extends [`Store`], adding the capability to create a store with
363/// a custom comparator, allowing to customize the ordering of values.
364///
365/// # Examples
366///
367/// ```
368/// use std::collections::HashMap;
369/// use zrx_store::comparator::Descending;
370/// use zrx_store::decorator::Ordered;
371/// use zrx_store::{StoreMut, StoreWithComparator};
372///
373/// // Create store
374/// let mut store: Ordered::<_, _, HashMap<_, _>, _> =
375///     Ordered::with_comparator(Descending);
376///
377/// // Insert value
378/// store.insert("key", 42);
379/// ```
380pub trait StoreWithComparator<K, V, C>: Store<K, V>
381where
382    C: Comparator<V>,
383{
384    /// Creates a store with the given comparator.
385    fn with_comparator(comparator: C) -> Self;
386}
387
388// ----------------------------------------------------------------------------
389
390/// Creates a store from an iterator.
391pub trait StoreFromIterator<K, V>: FromIterator<(K, V)> {}
392
393/// Creates an iterator over the items of the store.
394pub trait StoreIntoIterator<K, V>: IntoIterator<Item = (K, V)> {}
395
396// ----------------------------------------------------------------------------
397// Blanket implementations
398// ----------------------------------------------------------------------------
399
400#[rustfmt::skip]
401impl<K, V, T> StoreFromIterator<K, V> for T
402where
403    T: FromIterator<(K, V)> {}
404
405#[rustfmt::skip]
406impl<K, V, T> StoreIntoIterator<K, V> for T
407where
408    T: IntoIterator<Item = (K, V)> {}