Skip to main content

ruma_state_res/utils/
event_id_set.rs

1//! A set of event IDs.
2
3use std::{
4    borrow::Borrow,
5    collections::{HashSet, hash_set},
6    fmt,
7    hash::{Hash, RandomState},
8    iter::FusedIterator,
9};
10
11use ruma_common::EventId;
12
13/// A set of event IDs.
14#[derive(Clone, Debug)]
15pub struct EventIdSet<E: Borrow<EventId>>(HashSet<E>);
16
17impl<E: Borrow<EventId>> EventIdSet<E> {
18    /// Create an empty `EventIdSet`.
19    pub fn new() -> Self {
20        Self::default()
21    }
22
23    /// Create an empty `EventIdSet` with the given capacity.
24    pub fn with_capacity(capacity: usize) -> Self {
25        Self(HashSet::with_capacity(capacity))
26    }
27
28    /// Clears the set, removing all event IDs.
29    pub fn clear(&mut self) {
30        self.0.clear();
31    }
32
33    /// Returns the number of elements in the set.
34    pub fn len(&self) -> usize {
35        self.0.len()
36    }
37
38    /// Returns `true` if the set contains no elements.
39    pub fn is_empty(&self) -> bool {
40        self.0.is_empty()
41    }
42
43    /// Gets an iterator over the elements of the set.
44    pub fn iter(&self) -> EventIdSetIter<'_, E> {
45        EventIdSetIter(self.0.iter())
46    }
47}
48
49impl<E> EventIdSet<E>
50where
51    E: Borrow<EventId> + Eq + Hash,
52{
53    /// Returns `true` if the set contains the specified event ID.
54    pub fn contains(&self, event_id: &EventId) -> bool {
55        self.0.contains(event_id)
56    }
57
58    /// Returns a reference to the event ID in the set, if any, that is equal to the given one.
59    pub fn get(&self, event_id: &EventId) -> Option<&E> {
60        self.0.get(event_id)
61    }
62
63    /// Adds an event ID to the set.
64    ///
65    /// Returns whether the ID was newly inserted.
66    pub fn insert(&mut self, event_id: E) -> bool {
67        self.0.insert(event_id)
68    }
69
70    /// Removes an event ID from the set.
71    ///
72    /// Returns whether the ID was present in the set.
73    pub fn remove(&mut self, event_id: &EventId) -> bool {
74        self.0.remove(event_id)
75    }
76
77    /// Removes and returns the event ID in the set, if any, that is equal to the given one.
78    pub fn take(&mut self, event_id: &EventId) -> Option<E> {
79        self.0.take(event_id)
80    }
81
82    /// Visits the values representing the intersection, i.e., the values that are both in self and
83    /// other.
84    pub fn intersection<'a>(&'a self, other: &'a Self) -> EventIdSetIntersection<'a, E> {
85        EventIdSetIntersection(self.0.intersection(&other.0))
86    }
87}
88
89impl<E: Borrow<EventId>> Default for EventIdSet<E> {
90    fn default() -> Self {
91        Self(Default::default())
92    }
93}
94
95impl<E, const N: usize> From<[E; N]> for EventIdSet<E>
96where
97    E: Borrow<EventId> + Hash + Eq,
98{
99    fn from(value: [E; N]) -> Self {
100        Self(value.into())
101    }
102}
103
104impl<E> Extend<E> for EventIdSet<E>
105where
106    E: Borrow<EventId> + Hash + Eq,
107{
108    fn extend<T: IntoIterator<Item = E>>(&mut self, iter: T) {
109        self.0.extend(iter);
110    }
111}
112
113impl<E> FromIterator<E> for EventIdSet<E>
114where
115    E: Borrow<EventId> + Hash + Eq,
116{
117    fn from_iter<T: IntoIterator<Item = E>>(iter: T) -> Self {
118        Self(HashSet::from_iter(iter))
119    }
120}
121
122impl<E: Borrow<EventId>> IntoIterator for EventIdSet<E> {
123    type Item = E;
124    type IntoIter = EventIdSetIntoIter<E>;
125
126    fn into_iter(self) -> Self::IntoIter {
127        EventIdSetIntoIter(self.0.into_iter())
128    }
129}
130
131impl<'a, E: Borrow<EventId>> IntoIterator for &'a EventIdSet<E> {
132    type Item = &'a E;
133    type IntoIter = EventIdSetIter<'a, E>;
134
135    fn into_iter(self) -> Self::IntoIter {
136        self.iter()
137    }
138}
139
140/// An iterator over the values of an [`EventIdSet`].
141#[derive(Clone, Debug)]
142pub struct EventIdSetIter<'a, E>(hash_set::Iter<'a, E>);
143
144impl<'a, E> Iterator for EventIdSetIter<'a, E> {
145    type Item = &'a E;
146
147    fn next(&mut self) -> Option<Self::Item> {
148        self.0.next()
149    }
150
151    fn size_hint(&self) -> (usize, Option<usize>) {
152        self.0.size_hint()
153    }
154
155    fn count(self) -> usize {
156        self.0.len()
157    }
158
159    fn fold<B, F>(self, init: B, f: F) -> B
160    where
161        Self: Sized,
162        F: FnMut(B, Self::Item) -> B,
163    {
164        self.0.fold(init, f)
165    }
166}
167
168impl<'a, E> ExactSizeIterator for EventIdSetIter<'a, E> {}
169
170impl<'a, E> FusedIterator for EventIdSetIter<'a, E> {}
171
172/// An iterator over the values of an [`EventIdSet`].
173#[derive(Debug)]
174pub struct EventIdSetIntoIter<E>(hash_set::IntoIter<E>);
175
176impl<E> Iterator for EventIdSetIntoIter<E> {
177    type Item = E;
178
179    fn next(&mut self) -> Option<Self::Item> {
180        self.0.next()
181    }
182
183    fn size_hint(&self) -> (usize, Option<usize>) {
184        self.0.size_hint()
185    }
186
187    fn count(self) -> usize {
188        self.0.len()
189    }
190
191    fn fold<B, F>(self, init: B, f: F) -> B
192    where
193        Self: Sized,
194        F: FnMut(B, Self::Item) -> B,
195    {
196        self.0.fold(init, f)
197    }
198}
199
200impl<E> ExactSizeIterator for EventIdSetIntoIter<E> {}
201
202impl<E> FusedIterator for EventIdSetIntoIter<E> {}
203
204/// A lazy iterator producing elements in the intersection of [`EventIdSet`]s.
205#[derive(Clone)]
206pub struct EventIdSetIntersection<'a, E>(hash_set::Intersection<'a, E, RandomState>);
207
208impl<'a, E> fmt::Debug for EventIdSetIntersection<'a, E>
209where
210    E: fmt::Debug + Eq + Hash,
211{
212    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213        f.debug_tuple("EventIdSetIntersection").field(&self.0).finish()
214    }
215}
216
217impl<'a, E> Iterator for EventIdSetIntersection<'a, E>
218where
219    E: Eq + Hash,
220{
221    type Item = &'a E;
222
223    fn next(&mut self) -> Option<Self::Item> {
224        self.0.next()
225    }
226
227    fn size_hint(&self) -> (usize, Option<usize>) {
228        self.0.size_hint()
229    }
230
231    fn fold<B, F>(self, init: B, f: F) -> B
232    where
233        Self: Sized,
234        F: FnMut(B, Self::Item) -> B,
235    {
236        self.0.fold(init, f)
237    }
238}
239
240impl<'a, E> FusedIterator for EventIdSetIntersection<'a, E> where E: Eq + Hash {}