either_or_both/either/
iter.rs1use core::iter::FusedIterator;
4
5use crate::Either;
6
7#[derive(Debug, Clone, Default, PartialEq, Eq)]
9pub struct IntoIterEither<T>(Item<T>);
10
11#[derive(Debug, Clone, PartialEq, Eq)]
13struct Item<T>(Option<Either<T>>);
14
15#[derive(Debug, Clone, Default, PartialEq, Eq)]
17pub struct IterEither<'a, T>(Item<&'a T>);
18
19#[derive(Debug, Default, PartialEq, Eq)]
21pub struct IterMutEither<'a, T>(Item<&'a mut T>);
22
23#[derive(Debug, Clone)]
25pub struct InnerIterEither<T>(Either<T>);
26
27#[derive(Debug, Clone)]
29pub struct SwapIterEither<L, R>(Either<L, R>);
30
31impl<T> InnerIterEither<T> {
32 pub(crate) const fn new(either: Either<T, T>) -> Self {
33 Self(either)
34 }
35}
36
37impl<T> DoubleEndedIterator for InnerIterEither<T>
38where
39 T: DoubleEndedIterator,
40{
41 #[inline]
42 fn next_back(&mut self) -> Option<Self::Item> {
43 self.0.as_mut().reduce_map(DoubleEndedIterator::next_back)
44 }
45}
46
47impl<T> ExactSizeIterator for InnerIterEither<T> where T: ExactSizeIterator {}
48
49impl<T> FusedIterator for InnerIterEither<T> where T: FusedIterator {}
50
51impl<T> Iterator for InnerIterEither<T>
52where
53 T: Iterator,
54{
55 type Item = T::Item;
56
57 #[inline]
58 fn next(&mut self) -> Option<Self::Item> {
59 self.0.as_mut().reduce_map(Iterator::next)
60 }
61
62 #[inline]
63 fn size_hint(&self) -> (usize, Option<usize>) {
64 self.0.as_ref().reduce_map(Iterator::size_hint)
65 }
66}
67
68impl<T> IntoIterEither<T> {
69 pub(crate) fn new(either: Either<T>) -> Self {
70 Self(either.into())
71 }
72}
73
74impl<T> DoubleEndedIterator for IntoIterEither<T> {
75 #[inline]
76 fn next_back(&mut self) -> Option<Self::Item> {
77 self.0.next_back()
78 }
79}
80
81impl<T> ExactSizeIterator for IntoIterEither<T> {}
82impl<T> FusedIterator for IntoIterEither<T> {}
83
84impl<T> Iterator for IntoIterEither<T> {
85 type Item = T;
86
87 #[inline]
88 fn next(&mut self) -> Option<Self::Item> {
89 self.0.next()
90 }
91
92 #[inline]
93 fn size_hint(&self) -> (usize, Option<usize>) {
94 self.0.size_hint()
95 }
96}
97
98impl<T> From<Either<T>> for Item<T> {
99 fn from(value: Either<T>) -> Self {
100 Self(Some(value))
101 }
102}
103
104impl<T> Default for Item<T> {
105 fn default() -> Self {
106 Self(None)
107 }
108}
109
110impl<T> DoubleEndedIterator for Item<T> {
111 #[inline]
112 fn next_back(&mut self) -> Option<Self::Item> {
113 self.next()
114 }
115}
116
117impl<T> ExactSizeIterator for Item<T> {}
118impl<T> FusedIterator for Item<T> {}
119
120impl<T> Iterator for Item<T> {
121 type Item = T;
122
123 #[inline]
124 fn next(&mut self) -> Option<Self::Item> {
125 self.0.take().map(Either::reduce)
126 }
127
128 fn size_hint(&self) -> (usize, Option<usize>) {
129 match &self.0 {
130 Some(_) => (1, Some(1)),
131 None => (0, Some(0)),
132 }
133 }
134}
135
136impl<'a, T> IterEither<'a, T> {
137 pub(crate) fn new(either: &'a Either<T>) -> Self {
138 Self(either.as_ref().into())
139 }
140}
141
142impl<T> DoubleEndedIterator for IterEither<'_, T> {
143 #[inline]
144 fn next_back(&mut self) -> Option<Self::Item> {
145 self.0.next_back()
146 }
147}
148
149impl<T> ExactSizeIterator for IterEither<'_, T> {}
150impl<T> FusedIterator for IterEither<'_, T> {}
151
152impl<'a, T> Iterator for IterEither<'a, T> {
153 type Item = &'a T;
154
155 #[inline]
156 fn next(&mut self) -> Option<Self::Item> {
157 self.0.next()
158 }
159
160 #[inline]
161 fn size_hint(&self) -> (usize, Option<usize>) {
162 self.0.size_hint()
163 }
164}
165
166impl<'a, T> IterMutEither<'a, T> {
167 pub(crate) fn new(either: &'a mut Either<T>) -> Self {
168 Self(either.as_mut().into())
169 }
170}
171
172impl<T> DoubleEndedIterator for IterMutEither<'_, T> {
173 #[inline]
174 fn next_back(&mut self) -> Option<Self::Item> {
175 self.0.next_back()
176 }
177}
178
179impl<T> ExactSizeIterator for IterMutEither<'_, T> {}
180impl<T> FusedIterator for IterMutEither<'_, T> {}
181
182impl<'a, T> Iterator for IterMutEither<'a, T> {
183 type Item = &'a mut T;
184
185 #[inline]
186 fn next(&mut self) -> Option<Self::Item> {
187 self.0.next()
188 }
189
190 #[inline]
191 fn size_hint(&self) -> (usize, Option<usize>) {
192 self.0.size_hint()
193 }
194}
195
196impl<L, R> SwapIterEither<L, R> {
197 pub(crate) const fn new(either: Either<L, R>) -> Self {
198 Self(either)
199 }
200}
201
202impl<L, R> DoubleEndedIterator for SwapIterEither<L, R>
203where
204 L: DoubleEndedIterator,
205 R: DoubleEndedIterator,
206{
207 #[inline]
208 fn next_back(&mut self) -> Option<Self::Item> {
209 match self.0.as_mut() {
210 Either::Left(left) => left.next_back().map(Either::Left),
211 Either::Right(right) => right.next_back().map(Either::Right),
212 }
213 }
214}
215
216impl<L, R> ExactSizeIterator for SwapIterEither<L, R>
217where
218 L: ExactSizeIterator,
219 R: ExactSizeIterator,
220{
221}
222
223impl<L, R> FusedIterator for SwapIterEither<L, R>
224where
225 L: FusedIterator,
226 R: FusedIterator,
227{
228}
229
230impl<L, R> Iterator for SwapIterEither<L, R>
231where
232 L: Iterator,
233 R: Iterator,
234{
235 type Item = Either<L::Item, R::Item>;
236
237 #[inline]
238 fn next(&mut self) -> Option<Self::Item> {
239 match self.0.as_mut() {
240 Either::Left(left) => left.next().map(Either::Left),
241 Either::Right(right) => right.next().map(Either::Right),
242 }
243 }
244
245 fn size_hint(&self) -> (usize, Option<usize>) {
246 self.0
247 .as_ref()
248 .bireduce(Iterator::size_hint, Iterator::size_hint)
249 }
250}
251
252#[cfg(test)]
253mod tests {
254 use super::*;
255
256 #[test]
257 fn item_default() {
258 assert_eq!(Item::default(), Item::<u8>(None));
259 }
260}