Skip to main content

either/
iterator.rs

1use super::{Either, Left, Right};
2use core::iter;
3
4macro_rules! wrap_either {
5    ($value:expr => $( $tail:tt )*) => {
6        match $value {
7            Left(inner) => inner.map(Left) $($tail)*,
8            Right(inner) => inner.map(Right) $($tail)*,
9        }
10    };
11}
12
13/// Iterator that maps left or right iterators to corresponding `Either`-wrapped items.
14///
15/// This struct is created by the [`Either::factor_into_iter`],
16/// [`factor_iter`][Either::factor_iter],
17/// and [`factor_iter_mut`][Either::factor_iter_mut] methods.
18#[derive(Clone, Debug)]
19pub struct IterEither<L, R> {
20    inner: Either<L, R>,
21}
22
23impl<L, R> IterEither<L, R> {
24    pub(crate) fn new(inner: Either<L, R>) -> Self {
25        IterEither { inner }
26    }
27}
28
29impl<L, R, A> Extend<A> for Either<L, R>
30where
31    L: Extend<A>,
32    R: Extend<A>,
33{
34    fn extend<T>(&mut self, iter: T)
35    where
36        T: IntoIterator<Item = A>,
37    {
38        for_both!(self, inner => inner.extend(iter))
39    }
40}
41
42impl<A, B, L, R> Extend<Either<L, R>> for (A, B)
43where
44    A: Extend<L>,
45    B: Extend<R>,
46{
47    fn extend<T>(&mut self, iter: T)
48    where
49        T: IntoIterator<Item = Either<L, R>>,
50    {
51        iter.into_iter().for_each(move |item| match item {
52            // TODO: use `Extend::extend_one` <https://github.com/rust-lang/rust/issues/72631>
53            Left(item) => self.0.extend(iter::once(item)),
54            Right(item) => self.1.extend(iter::once(item)),
55        });
56    }
57}
58
59/// Collects `Left` and `Right` items into separate collections
60///
61/// ```
62/// use either::Either::*;
63/// let (threes, other): (Vec<i32>, Vec<i32>) = (1..10)
64///     .map(|i| if i % 3 == 0 { Left(i) } else { Right(i) })
65///     .collect();
66/// assert_eq!(threes, [3, 6, 9]);
67/// assert_eq!(other, [1, 2, 4, 5, 7, 8]);
68/// ```
69impl<A, B, L, R> FromIterator<Either<L, R>> for (A, B)
70where
71    A: Default + Extend<L>,
72    B: Default + Extend<R>,
73{
74    fn from_iter<T>(iter: T) -> Self
75    where
76        T: IntoIterator<Item = Either<L, R>>,
77    {
78        let mut pair = (A::default(), B::default());
79        pair.extend(iter);
80        pair
81    }
82}
83
84/// `Either<L, R>` is an iterator if both `L` and `R` are iterators.
85impl<L, R> Iterator for Either<L, R>
86where
87    L: Iterator,
88    R: Iterator<Item = L::Item>,
89{
90    type Item = L::Item;
91
92    fn next(&mut self) -> Option<Self::Item> {
93        for_both!(self, inner => inner.next())
94    }
95
96    fn size_hint(&self) -> (usize, Option<usize>) {
97        for_both!(self, inner => inner.size_hint())
98    }
99
100    fn fold<Acc, G>(self, init: Acc, f: G) -> Acc
101    where
102        G: FnMut(Acc, Self::Item) -> Acc,
103    {
104        for_both!(self, inner => inner.fold(init, f))
105    }
106
107    fn for_each<F>(self, f: F)
108    where
109        F: FnMut(Self::Item),
110    {
111        for_both!(self, inner => inner.for_each(f))
112    }
113
114    fn count(self) -> usize {
115        for_both!(self, inner => inner.count())
116    }
117
118    fn last(self) -> Option<Self::Item> {
119        for_both!(self, inner => inner.last())
120    }
121
122    fn nth(&mut self, n: usize) -> Option<Self::Item> {
123        for_both!(self, inner => inner.nth(n))
124    }
125
126    fn collect<B>(self) -> B
127    where
128        B: iter::FromIterator<Self::Item>,
129    {
130        for_both!(self, inner => inner.collect())
131    }
132
133    fn partition<B, F>(self, f: F) -> (B, B)
134    where
135        B: Default + Extend<Self::Item>,
136        F: FnMut(&Self::Item) -> bool,
137    {
138        for_both!(self, inner => inner.partition(f))
139    }
140
141    fn all<F>(&mut self, f: F) -> bool
142    where
143        F: FnMut(Self::Item) -> bool,
144    {
145        for_both!(self, inner => inner.all(f))
146    }
147
148    fn any<F>(&mut self, f: F) -> bool
149    where
150        F: FnMut(Self::Item) -> bool,
151    {
152        for_both!(self, inner => inner.any(f))
153    }
154
155    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
156    where
157        P: FnMut(&Self::Item) -> bool,
158    {
159        for_both!(self, inner => inner.find(predicate))
160    }
161
162    fn find_map<B, F>(&mut self, f: F) -> Option<B>
163    where
164        F: FnMut(Self::Item) -> Option<B>,
165    {
166        for_both!(self, inner => inner.find_map(f))
167    }
168
169    fn position<P>(&mut self, predicate: P) -> Option<usize>
170    where
171        P: FnMut(Self::Item) -> bool,
172    {
173        for_both!(self, inner => inner.position(predicate))
174    }
175}
176
177impl<L, R> DoubleEndedIterator for Either<L, R>
178where
179    L: DoubleEndedIterator,
180    R: DoubleEndedIterator<Item = L::Item>,
181{
182    fn next_back(&mut self) -> Option<Self::Item> {
183        for_both!(self, inner => inner.next_back())
184    }
185
186    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
187        for_both!(self, inner => inner.nth_back(n))
188    }
189
190    fn rfold<Acc, G>(self, init: Acc, f: G) -> Acc
191    where
192        G: FnMut(Acc, Self::Item) -> Acc,
193    {
194        for_both!(self, inner => inner.rfold(init, f))
195    }
196
197    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
198    where
199        P: FnMut(&Self::Item) -> bool,
200    {
201        for_both!(self, inner => inner.rfind(predicate))
202    }
203}
204
205impl<L, R> ExactSizeIterator for Either<L, R>
206where
207    L: ExactSizeIterator,
208    R: ExactSizeIterator<Item = L::Item>,
209{
210    fn len(&self) -> usize {
211        for_both!(self, inner => inner.len())
212    }
213}
214
215impl<L, R> iter::FusedIterator for Either<L, R>
216where
217    L: iter::FusedIterator,
218    R: iter::FusedIterator<Item = L::Item>,
219{
220}
221
222impl<L, R> Iterator for IterEither<L, R>
223where
224    L: Iterator,
225    R: Iterator,
226{
227    type Item = Either<L::Item, R::Item>;
228
229    fn next(&mut self) -> Option<Self::Item> {
230        Some(map_both!(self.inner, ref mut inner => inner.next()?))
231    }
232
233    fn size_hint(&self) -> (usize, Option<usize>) {
234        for_both!(self.inner, ref inner => inner.size_hint())
235    }
236
237    fn fold<Acc, G>(self, init: Acc, f: G) -> Acc
238    where
239        G: FnMut(Acc, Self::Item) -> Acc,
240    {
241        wrap_either!(self.inner => .fold(init, f))
242    }
243
244    fn for_each<F>(self, f: F)
245    where
246        F: FnMut(Self::Item),
247    {
248        wrap_either!(self.inner => .for_each(f))
249    }
250
251    fn count(self) -> usize {
252        for_both!(self.inner, inner => inner.count())
253    }
254
255    fn last(self) -> Option<Self::Item> {
256        Some(map_both!(self.inner, inner => inner.last()?))
257    }
258
259    fn nth(&mut self, n: usize) -> Option<Self::Item> {
260        Some(map_both!(self.inner, ref mut inner => inner.nth(n)?))
261    }
262
263    fn collect<B>(self) -> B
264    where
265        B: iter::FromIterator<Self::Item>,
266    {
267        wrap_either!(self.inner => .collect())
268    }
269
270    fn partition<B, F>(self, f: F) -> (B, B)
271    where
272        B: Default + Extend<Self::Item>,
273        F: FnMut(&Self::Item) -> bool,
274    {
275        wrap_either!(self.inner => .partition(f))
276    }
277
278    fn all<F>(&mut self, f: F) -> bool
279    where
280        F: FnMut(Self::Item) -> bool,
281    {
282        wrap_either!(&mut self.inner => .all(f))
283    }
284
285    fn any<F>(&mut self, f: F) -> bool
286    where
287        F: FnMut(Self::Item) -> bool,
288    {
289        wrap_either!(&mut self.inner => .any(f))
290    }
291
292    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
293    where
294        P: FnMut(&Self::Item) -> bool,
295    {
296        wrap_either!(&mut self.inner => .find(predicate))
297    }
298
299    fn find_map<B, F>(&mut self, f: F) -> Option<B>
300    where
301        F: FnMut(Self::Item) -> Option<B>,
302    {
303        wrap_either!(&mut self.inner => .find_map(f))
304    }
305
306    fn position<P>(&mut self, predicate: P) -> Option<usize>
307    where
308        P: FnMut(Self::Item) -> bool,
309    {
310        wrap_either!(&mut self.inner => .position(predicate))
311    }
312}
313
314impl<L, R> DoubleEndedIterator for IterEither<L, R>
315where
316    L: DoubleEndedIterator,
317    R: DoubleEndedIterator,
318{
319    fn next_back(&mut self) -> Option<Self::Item> {
320        Some(map_both!(self.inner, ref mut inner => inner.next_back()?))
321    }
322
323    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
324        Some(map_both!(self.inner, ref mut inner => inner.nth_back(n)?))
325    }
326
327    fn rfold<Acc, G>(self, init: Acc, f: G) -> Acc
328    where
329        G: FnMut(Acc, Self::Item) -> Acc,
330    {
331        wrap_either!(self.inner => .rfold(init, f))
332    }
333
334    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
335    where
336        P: FnMut(&Self::Item) -> bool,
337    {
338        wrap_either!(&mut self.inner => .rfind(predicate))
339    }
340}
341
342impl<L, R> ExactSizeIterator for IterEither<L, R>
343where
344    L: ExactSizeIterator,
345    R: ExactSizeIterator,
346{
347    fn len(&self) -> usize {
348        for_both!(self.inner, ref inner => inner.len())
349    }
350}
351
352impl<L, R> iter::FusedIterator for IterEither<L, R>
353where
354    L: iter::FusedIterator,
355    R: iter::FusedIterator,
356{
357}