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    #[inline]
101    fn fold<Acc, G>(self, init: Acc, f: G) -> Acc
102    where
103        G: FnMut(Acc, Self::Item) -> Acc,
104    {
105        for_both!(self, inner => inner.fold(init, f))
106    }
107
108    fn for_each<F>(self, f: F)
109    where
110        F: FnMut(Self::Item),
111    {
112        for_both!(self, inner => inner.for_each(f))
113    }
114
115    fn count(self) -> usize {
116        for_both!(self, inner => inner.count())
117    }
118
119    fn last(self) -> Option<Self::Item> {
120        for_both!(self, inner => inner.last())
121    }
122
123    fn nth(&mut self, n: usize) -> Option<Self::Item> {
124        for_both!(self, inner => inner.nth(n))
125    }
126
127    fn collect<B>(self) -> B
128    where
129        B: iter::FromIterator<Self::Item>,
130    {
131        for_both!(self, inner => inner.collect())
132    }
133
134    fn partition<B, F>(self, f: F) -> (B, B)
135    where
136        B: Default + Extend<Self::Item>,
137        F: FnMut(&Self::Item) -> bool,
138    {
139        for_both!(self, inner => inner.partition(f))
140    }
141
142    fn all<F>(&mut self, f: F) -> bool
143    where
144        F: FnMut(Self::Item) -> bool,
145    {
146        for_both!(self, inner => inner.all(f))
147    }
148
149    fn any<F>(&mut self, f: F) -> bool
150    where
151        F: FnMut(Self::Item) -> bool,
152    {
153        for_both!(self, inner => inner.any(f))
154    }
155
156    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
157    where
158        P: FnMut(&Self::Item) -> bool,
159    {
160        for_both!(self, inner => inner.find(predicate))
161    }
162
163    fn find_map<B, F>(&mut self, f: F) -> Option<B>
164    where
165        F: FnMut(Self::Item) -> Option<B>,
166    {
167        for_both!(self, inner => inner.find_map(f))
168    }
169
170    fn position<P>(&mut self, predicate: P) -> Option<usize>
171    where
172        P: FnMut(Self::Item) -> bool,
173    {
174        for_both!(self, inner => inner.position(predicate))
175    }
176}
177
178impl<L, R> DoubleEndedIterator for Either<L, R>
179where
180    L: DoubleEndedIterator,
181    R: DoubleEndedIterator<Item = L::Item>,
182{
183    fn next_back(&mut self) -> Option<Self::Item> {
184        for_both!(self, inner => inner.next_back())
185    }
186
187    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
188        for_both!(self, inner => inner.nth_back(n))
189    }
190
191    #[inline]
192    fn rfold<Acc, G>(self, init: Acc, f: G) -> Acc
193    where
194        G: FnMut(Acc, Self::Item) -> Acc,
195    {
196        for_both!(self, inner => inner.rfold(init, f))
197    }
198
199    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
200    where
201        P: FnMut(&Self::Item) -> bool,
202    {
203        for_both!(self, inner => inner.rfind(predicate))
204    }
205}
206
207impl<L, R> ExactSizeIterator for Either<L, R>
208where
209    L: ExactSizeIterator,
210    R: ExactSizeIterator<Item = L::Item>,
211{
212    fn len(&self) -> usize {
213        for_both!(self, inner => inner.len())
214    }
215}
216
217impl<L, R> iter::FusedIterator for Either<L, R>
218where
219    L: iter::FusedIterator,
220    R: iter::FusedIterator<Item = L::Item>,
221{
222}
223
224impl<L, R> Iterator for IterEither<L, R>
225where
226    L: Iterator,
227    R: Iterator,
228{
229    type Item = Either<L::Item, R::Item>;
230
231    fn next(&mut self) -> Option<Self::Item> {
232        Some(map_both!(self.inner, ref mut inner => inner.next()?))
233    }
234
235    fn size_hint(&self) -> (usize, Option<usize>) {
236        for_both!(self.inner, ref inner => inner.size_hint())
237    }
238
239    #[inline]
240    fn fold<Acc, G>(self, init: Acc, f: G) -> Acc
241    where
242        G: FnMut(Acc, Self::Item) -> Acc,
243    {
244        wrap_either!(self.inner => .fold(init, f))
245    }
246
247    fn for_each<F>(self, f: F)
248    where
249        F: FnMut(Self::Item),
250    {
251        wrap_either!(self.inner => .for_each(f))
252    }
253
254    fn count(self) -> usize {
255        for_both!(self.inner, inner => inner.count())
256    }
257
258    fn last(self) -> Option<Self::Item> {
259        Some(map_both!(self.inner, inner => inner.last()?))
260    }
261
262    fn nth(&mut self, n: usize) -> Option<Self::Item> {
263        Some(map_both!(self.inner, ref mut inner => inner.nth(n)?))
264    }
265
266    fn collect<B>(self) -> B
267    where
268        B: iter::FromIterator<Self::Item>,
269    {
270        wrap_either!(self.inner => .collect())
271    }
272
273    fn partition<B, F>(self, f: F) -> (B, B)
274    where
275        B: Default + Extend<Self::Item>,
276        F: FnMut(&Self::Item) -> bool,
277    {
278        wrap_either!(self.inner => .partition(f))
279    }
280
281    fn all<F>(&mut self, f: F) -> bool
282    where
283        F: FnMut(Self::Item) -> bool,
284    {
285        wrap_either!(&mut self.inner => .all(f))
286    }
287
288    fn any<F>(&mut self, f: F) -> bool
289    where
290        F: FnMut(Self::Item) -> bool,
291    {
292        wrap_either!(&mut self.inner => .any(f))
293    }
294
295    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
296    where
297        P: FnMut(&Self::Item) -> bool,
298    {
299        wrap_either!(&mut self.inner => .find(predicate))
300    }
301
302    fn find_map<B, F>(&mut self, f: F) -> Option<B>
303    where
304        F: FnMut(Self::Item) -> Option<B>,
305    {
306        wrap_either!(&mut self.inner => .find_map(f))
307    }
308
309    fn position<P>(&mut self, predicate: P) -> Option<usize>
310    where
311        P: FnMut(Self::Item) -> bool,
312    {
313        wrap_either!(&mut self.inner => .position(predicate))
314    }
315}
316
317impl<L, R> DoubleEndedIterator for IterEither<L, R>
318where
319    L: DoubleEndedIterator,
320    R: DoubleEndedIterator,
321{
322    fn next_back(&mut self) -> Option<Self::Item> {
323        Some(map_both!(self.inner, ref mut inner => inner.next_back()?))
324    }
325
326    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
327        Some(map_both!(self.inner, ref mut inner => inner.nth_back(n)?))
328    }
329
330    #[inline]
331    fn rfold<Acc, G>(self, init: Acc, f: G) -> Acc
332    where
333        G: FnMut(Acc, Self::Item) -> Acc,
334    {
335        wrap_either!(self.inner => .rfold(init, f))
336    }
337
338    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
339    where
340        P: FnMut(&Self::Item) -> bool,
341    {
342        wrap_either!(&mut self.inner => .rfind(predicate))
343    }
344}
345
346impl<L, R> ExactSizeIterator for IterEither<L, R>
347where
348    L: ExactSizeIterator,
349    R: ExactSizeIterator,
350{
351    fn len(&self) -> usize {
352        for_both!(self.inner, ref inner => inner.len())
353    }
354}
355
356impl<L, R> iter::FusedIterator for IterEither<L, R>
357where
358    L: iter::FusedIterator,
359    R: iter::FusedIterator,
360{
361}