multi_stash/
iter.rs

1use super::{Entry, Key, MultiStash};
2use alloc::vec;
3use core::iter::{Enumerate, FusedIterator};
4use core::slice;
5
6/// Immutable [`MultiStash`] iterator.
7///
8/// This struct is created by [`MultiStash::iter`].
9#[derive(Debug)]
10pub struct Iter<'a, T> {
11    /// The amount of remaining `Entry::Occupied` entries.
12    remaining: usize,
13    /// Iterator over the entries of the `MultiStash`.
14    iter: Enumerate<slice::Iter<'a, Entry<T>>>,
15}
16
17impl<'a, T> Iter<'a, T> {
18    /// Creates a new [`Iter`] for the [`MultiStash`].
19    pub(crate) fn new(stash: &'a MultiStash<T>) -> Self {
20        Self {
21            remaining: stash.len_occupied,
22            iter: stash.entries.iter().enumerate(),
23        }
24    }
25}
26
27impl<'a, T> Iterator for Iter<'a, T> {
28    type Item = (Key, usize, &'a T);
29
30    fn next(&mut self) -> Option<Self::Item> {
31        loop {
32            match self.iter.next() {
33                None => return None,
34                Some((_, Entry::Vacant(_))) => continue,
35                Some((index, Entry::Occupied(entry))) => {
36                    self.remaining -= 1;
37                    return Some((Key(index), entry.remaining.get(), &entry.item));
38                }
39            }
40        }
41    }
42}
43
44impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
45    fn next_back(&mut self) -> Option<Self::Item> {
46        loop {
47            match self.iter.next_back() {
48                None => return None,
49                Some((_, Entry::Vacant(_))) => continue,
50                Some((index, Entry::Occupied(entry))) => {
51                    self.remaining -= 1;
52                    return Some((Key(index), entry.remaining.get(), &entry.item));
53                }
54            }
55        }
56    }
57}
58
59impl<'a, T> ExactSizeIterator for Iter<'a, T> {
60    fn len(&self) -> usize {
61        self.remaining
62    }
63}
64
65impl<'a, T> FusedIterator for Iter<'a, T> {}
66
67/// Mutable [`MultiStash`] iterator.
68///
69/// This struct is created by [`MultiStash::iter_mut`].
70#[derive(Debug)]
71pub struct IterMut<'a, T> {
72    /// The amount of remaining `Entry::Occupied` entries.
73    remaining: usize,
74    /// Iterator over the entries of the `MultiStash`.
75    iter: Enumerate<slice::IterMut<'a, Entry<T>>>,
76}
77
78impl<'a, T> IterMut<'a, T> {
79    /// Creates a new [`IterMut`] for the [`MultiStash`].
80    pub(crate) fn new(stash: &'a mut MultiStash<T>) -> Self {
81        Self {
82            remaining: stash.len_occupied,
83            iter: stash.entries.iter_mut().enumerate(),
84        }
85    }
86}
87
88impl<'a, T> Iterator for IterMut<'a, T> {
89    type Item = (Key, usize, &'a mut T);
90
91    fn next(&mut self) -> Option<Self::Item> {
92        loop {
93            match self.iter.next() {
94                None => return None,
95                Some((_, Entry::Vacant(_))) => continue,
96                Some((index, Entry::Occupied(entry))) => {
97                    self.remaining -= 1;
98                    return Some((Key(index), entry.remaining.get(), &mut entry.item));
99                }
100            }
101        }
102    }
103}
104
105impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
106    fn next_back(&mut self) -> Option<Self::Item> {
107        loop {
108            match self.iter.next_back() {
109                None => return None,
110                Some((_, Entry::Vacant(_))) => continue,
111                Some((index, Entry::Occupied(entry))) => {
112                    self.remaining -= 1;
113                    return Some((Key(index), entry.remaining.get(), &mut entry.item));
114                }
115            }
116        }
117    }
118}
119
120impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
121    fn len(&self) -> usize {
122        self.remaining
123    }
124}
125
126impl<'a, T> FusedIterator for IterMut<'a, T> {}
127
128/// An iterator that moves out of a [`MultiStash`].
129///
130/// This `struct` is created by the `into_iter` method on [`MultiStash`]
131/// (provided by the [`IntoIterator`] trait).
132#[derive(Debug)]
133pub struct IntoIter<T> {
134    /// The amount of remaining `Entry::Occupied` entries.
135    remaining: usize,
136    /// Iterator over the entries of the `MultiStash`.
137    iter: Enumerate<vec::IntoIter<Entry<T>>>,
138}
139
140impl<T> IntoIter<T> {
141    /// Creates a new [`IntoIter`] for the [`MultiStash`].
142    pub(crate) fn new(stash: MultiStash<T>) -> Self {
143        Self {
144            remaining: stash.len_occupied,
145            iter: stash.entries.into_iter().enumerate(),
146        }
147    }
148}
149
150impl<T> Iterator for IntoIter<T> {
151    type Item = (Key, usize, T);
152
153    fn next(&mut self) -> Option<Self::Item> {
154        loop {
155            match self.iter.next() {
156                None => return None,
157                Some((_, Entry::Vacant(_))) => continue,
158                Some((index, Entry::Occupied(entry))) => {
159                    self.remaining -= 1;
160                    return Some((Key(index), entry.remaining.get(), entry.item));
161                }
162            }
163        }
164    }
165}
166
167impl<T> DoubleEndedIterator for IntoIter<T> {
168    fn next_back(&mut self) -> Option<Self::Item> {
169        loop {
170            match self.iter.next_back() {
171                None => return None,
172                Some((_, Entry::Vacant(_))) => continue,
173                Some((index, Entry::Occupied(entry))) => {
174                    self.remaining -= 1;
175                    return Some((Key(index), entry.remaining.get(), entry.item));
176                }
177            }
178        }
179    }
180}
181
182impl<T> ExactSizeIterator for IntoIter<T> {
183    fn len(&self) -> usize {
184        self.remaining
185    }
186}
187
188impl<T> FusedIterator for IntoIter<T> {}