Skip to main content

zrx_store/store/
collection.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//! Collection.
27
28use std::any::Any;
29use std::fmt::Debug;
30
31use crate::store::item::{Key, Value};
32use crate::store::{Store, StoreIterable, StoreKeys, StoreMut, StoreValues};
33
34// ----------------------------------------------------------------------------
35// Traits
36// ----------------------------------------------------------------------------
37
38/// Collection.
39///
40/// This trait combines the following traits, which are not dyn-compatible for
41/// reasons of flexibility, into a single trait object that allows to erase the
42/// type of the underlying store while preserving the types of the key and value
43/// type parameters, `K` and `V`:
44///
45/// - [`Store`]
46/// - [`StoreMut`]
47/// - [`StoreIterable`]
48/// - [`StoreKeys`]
49/// - [`StoreValues`]
50///
51/// Additionally, implementors must implement [`Any`], so a [`Collection`] can
52/// be downcast to an immutable or mutable reference of its concrete type, if
53/// necessary and known, as well as [`Debug`], in order to conveniently print
54/// the contents of the collection.
55///
56/// We also provide a blanket implementation for implementors which fulfill all
57/// of the aforementioned traits, so that they can be used as a [`Collection`].
58pub trait Collection<K, V>: Any + Debug {
59    /// Returns a reference to the value identified by the key.
60    fn get(&self, key: &K) -> Option<&V>;
61
62    /// Returns whether the collection contains the key.
63    fn contains_key(&self, id: &K) -> bool;
64
65    /// Returns the number of items in the collection.
66    fn len(&self) -> usize;
67
68    /// Returns whether the collection is empty.
69    fn is_empty(&self) -> bool;
70
71    /// Inserts the value identified by the key.
72    fn insert(&mut self, key: K, value: V) -> Option<V>;
73
74    /// Removes the value identified by the key.
75    fn remove(&mut self, key: &K) -> Option<V>;
76
77    /// Removes the value identified by the key and returns both.
78    fn remove_entry(&mut self, key: &K) -> Option<(K, V)>;
79
80    /// Clears the collection, removing all items.
81    fn clear(&mut self);
82
83    /// Creates an iterator over the items of the collection.
84    fn iter(&self) -> Iter<'_, K, V>;
85
86    /// Creates an iterator over the keys of the collection.
87    fn keys(&self) -> Keys<'_, K>;
88
89    /// Creates an iterator over the values of the collection.
90    fn values(&self) -> Values<'_, V>;
91}
92
93// ----------------------------------------------------------------------------
94// Implementations
95// ----------------------------------------------------------------------------
96
97impl<K, V> dyn Collection<K, V> {
98    /// Attempts to downcast to a reference of `T`.
99    #[inline]
100    #[must_use]
101    pub fn downcast_ref<T>(&self) -> Option<&T>
102    where
103        T: Collection<K, V> + Any,
104    {
105        (self as &dyn Any).downcast_ref()
106    }
107
108    /// Attempts to downcast to a mutable reference of `T`.
109    #[inline]
110    #[must_use]
111    pub fn downcast_mut<T>(&mut self) -> Option<&mut T>
112    where
113        T: Collection<K, V> + Any,
114    {
115        (self as &mut dyn Any).downcast_mut()
116    }
117}
118
119// ----------------------------------------------------------------------------
120// Trait implementations
121// ----------------------------------------------------------------------------
122
123impl<'a, K, V> IntoIterator for &'a dyn Collection<K, V>
124where
125    K: Key,
126    V: Value,
127{
128    type Item = (&'a K, &'a V);
129    type IntoIter = Iter<'a, K, V>;
130
131    /// Creates an iterator over the items of the collection.
132    #[inline]
133    fn into_iter(self) -> Self::IntoIter {
134        self.iter()
135    }
136}
137
138// ----------------------------------------------------------------------------
139// Blanket implementations
140// ----------------------------------------------------------------------------
141
142impl<K, V, S> Collection<K, V> for S
143where
144    K: Key,
145    V: Value,
146    S: Any + Debug,
147    S: Store<K, V>
148        + StoreMut<K, V>
149        + StoreIterable<K, V>
150        + StoreKeys<K, V>
151        + StoreValues<K, V>,
152{
153    /// Returns a reference to the value identified by the key.
154    #[inline]
155    fn get(&self, id: &K) -> Option<&V> {
156        Store::get(self, id)
157    }
158
159    /// Returns whether the collection contains the key.
160    #[inline]
161    fn contains_key(&self, id: &K) -> bool {
162        Store::contains_key(self, id)
163    }
164
165    /// Returns the number of items in the collection.
166    #[inline]
167    fn len(&self) -> usize {
168        Store::len(self)
169    }
170
171    /// Returns whether the collection is empty.
172    #[inline]
173    fn is_empty(&self) -> bool {
174        Store::is_empty(self)
175    }
176
177    /// Inserts the value identified by the key.
178    #[inline]
179    fn insert(&mut self, key: K, value: V) -> Option<V> {
180        StoreMut::insert(self, key, value)
181    }
182
183    /// Removes the value identified by the key.
184    #[inline]
185    fn remove(&mut self, key: &K) -> Option<V> {
186        StoreMut::remove(self, key)
187    }
188
189    /// Removes the value identified by the key and returns both.
190    #[inline]
191    fn remove_entry(&mut self, key: &K) -> Option<(K, V)> {
192        StoreMut::remove_entry(self, key)
193    }
194
195    /// Clears the collection, removing all items.
196    #[inline]
197    fn clear(&mut self) {
198        StoreMut::clear(self);
199    }
200
201    /// Creates an iterator over the items of the collection.
202    #[inline]
203    fn iter(&self) -> Iter<'_, K, V> {
204        Box::new(StoreIterable::iter(self))
205    }
206
207    /// Creates an iterator over the keys of the collection.
208    #[inline]
209    fn keys(&self) -> Keys<'_, K> {
210        Box::new(StoreKeys::keys(self))
211    }
212
213    /// Creates an iterator over the values of the collection.
214    #[inline]
215    fn values(&self) -> Values<'_, V> {
216        Box::new(StoreValues::values(self))
217    }
218}
219
220// ----------------------------------------------------------------------------
221// Type aliases
222// ----------------------------------------------------------------------------
223
224/// Iterator over the items of a [`Collection`].
225pub type Iter<'a, K, V> = Box<dyn Iterator<Item = (&'a K, &'a V)> + 'a>;
226
227/// Iterator over the keys of a [`Collection`].
228pub type Keys<'a, K> = Box<dyn Iterator<Item = &'a K> + 'a>;
229
230/// Iterator over the values of a [`Collection`].
231pub type Values<'a, V> = Box<dyn Iterator<Item = &'a V> + 'a>;