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>;