1use super::{for_both, 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, ref mut inner => inner.extend(iter))
39 }
40}
41
42/// `Either<L, R>` is an iterator if both `L` and `R` are iterators.
43impl<L, R> Iterator for Either<L, R>
44where
45 L: Iterator,
46 R: Iterator<Item = L::Item>,
47{
48 type Item = L::Item;
49
50 fn next(&mut self) -> Option<Self::Item> {
51 for_both!(*self, ref mut inner => inner.next())
52 }
53
54 fn size_hint(&self) -> (usize, Option<usize>) {
55 for_both!(*self, ref inner => inner.size_hint())
56 }
57
58 fn fold<Acc, G>(self, init: Acc, f: G) -> Acc
59 where
60 G: FnMut(Acc, Self::Item) -> Acc,
61 {
62 for_both!(self, inner => inner.fold(init, f))
63 }
64
65 fn for_each<F>(self, f: F)
66 where
67 F: FnMut(Self::Item),
68 {
69 for_both!(self, inner => inner.for_each(f))
70 }
71
72 fn count(self) -> usize {
73 for_both!(self, inner => inner.count())
74 }
75
76 fn last(self) -> Option<Self::Item> {
77 for_both!(self, inner => inner.last())
78 }
79
80 fn nth(&mut self, n: usize) -> Option<Self::Item> {
81 for_both!(*self, ref mut inner => inner.nth(n))
82 }
83
84 fn collect<B>(self) -> B
85 where
86 B: iter::FromIterator<Self::Item>,
87 {
88 for_both!(self, inner => inner.collect())
89 }
90
91 fn partition<B, F>(self, f: F) -> (B, B)
92 where
93 B: Default + Extend<Self::Item>,
94 F: FnMut(&Self::Item) -> bool,
95 {
96 for_both!(self, inner => inner.partition(f))
97 }
98
99 fn all<F>(&mut self, f: F) -> bool
100 where
101 F: FnMut(Self::Item) -> bool,
102 {
103 for_both!(*self, ref mut inner => inner.all(f))
104 }
105
106 fn any<F>(&mut self, f: F) -> bool
107 where
108 F: FnMut(Self::Item) -> bool,
109 {
110 for_both!(*self, ref mut inner => inner.any(f))
111 }
112
113 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
114 where
115 P: FnMut(&Self::Item) -> bool,
116 {
117 for_both!(*self, ref mut inner => inner.find(predicate))
118 }
119
120 fn find_map<B, F>(&mut self, f: F) -> Option<B>
121 where
122 F: FnMut(Self::Item) -> Option<B>,
123 {
124 for_both!(*self, ref mut inner => inner.find_map(f))
125 }
126
127 fn position<P>(&mut self, predicate: P) -> Option<usize>
128 where
129 P: FnMut(Self::Item) -> bool,
130 {
131 for_both!(*self, ref mut inner => inner.position(predicate))
132 }
133}
134
135impl<L, R> DoubleEndedIterator for Either<L, R>
136where
137 L: DoubleEndedIterator,
138 R: DoubleEndedIterator<Item = L::Item>,
139{
140 fn next_back(&mut self) -> Option<Self::Item> {
141 for_both!(*self, ref mut inner => inner.next_back())
142 }
143
144 // TODO(MSRV): This was stabilized in Rust 1.37
145 // fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
146 // for_both!(*self, ref mut inner => inner.nth_back(n))
147 // }
148
149 fn rfold<Acc, G>(self, init: Acc, f: G) -> Acc
150 where
151 G: FnMut(Acc, Self::Item) -> Acc,
152 {
153 for_both!(self, inner => inner.rfold(init, f))
154 }
155
156 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
157 where
158 P: FnMut(&Self::Item) -> bool,
159 {
160 for_both!(*self, ref mut inner => inner.rfind(predicate))
161 }
162}
163
164impl<L, R> ExactSizeIterator for Either<L, R>
165where
166 L: ExactSizeIterator,
167 R: ExactSizeIterator<Item = L::Item>,
168{
169 fn len(&self) -> usize {
170 for_both!(*self, ref inner => inner.len())
171 }
172}
173
174impl<L, R> iter::FusedIterator for Either<L, R>
175where
176 L: iter::FusedIterator,
177 R: iter::FusedIterator<Item = L::Item>,
178{
179}
180
181impl<L, R> Iterator for IterEither<L, R>
182where
183 L: Iterator,
184 R: Iterator,
185{
186 type Item = Either<L::Item, R::Item>;
187
188 fn next(&mut self) -> Option<Self::Item> {
189 Some(map_either!(self.inner, ref mut inner => inner.next()?))
190 }
191
192 fn size_hint(&self) -> (usize, Option<usize>) {
193 for_both!(self.inner, ref inner => inner.size_hint())
194 }
195
196 fn fold<Acc, G>(self, init: Acc, f: G) -> Acc
197 where
198 G: FnMut(Acc, Self::Item) -> Acc,
199 {
200 wrap_either!(self.inner => .fold(init, f))
201 }
202
203 fn for_each<F>(self, f: F)
204 where
205 F: FnMut(Self::Item),
206 {
207 wrap_either!(self.inner => .for_each(f))
208 }
209
210 fn count(self) -> usize {
211 for_both!(self.inner, inner => inner.count())
212 }
213
214 fn last(self) -> Option<Self::Item> {
215 Some(map_either!(self.inner, inner => inner.last()?))
216 }
217
218 fn nth(&mut self, n: usize) -> Option<Self::Item> {
219 Some(map_either!(self.inner, ref mut inner => inner.nth(n)?))
220 }
221
222 fn collect<B>(self) -> B
223 where
224 B: iter::FromIterator<Self::Item>,
225 {
226 wrap_either!(self.inner => .collect())
227 }
228
229 fn partition<B, F>(self, f: F) -> (B, B)
230 where
231 B: Default + Extend<Self::Item>,
232 F: FnMut(&Self::Item) -> bool,
233 {
234 wrap_either!(self.inner => .partition(f))
235 }
236
237 fn all<F>(&mut self, f: F) -> bool
238 where
239 F: FnMut(Self::Item) -> bool,
240 {
241 wrap_either!(&mut self.inner => .all(f))
242 }
243
244 fn any<F>(&mut self, f: F) -> bool
245 where
246 F: FnMut(Self::Item) -> bool,
247 {
248 wrap_either!(&mut self.inner => .any(f))
249 }
250
251 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
252 where
253 P: FnMut(&Self::Item) -> bool,
254 {
255 wrap_either!(&mut self.inner => .find(predicate))
256 }
257
258 fn find_map<B, F>(&mut self, f: F) -> Option<B>
259 where
260 F: FnMut(Self::Item) -> Option<B>,
261 {
262 wrap_either!(&mut self.inner => .find_map(f))
263 }
264
265 fn position<P>(&mut self, predicate: P) -> Option<usize>
266 where
267 P: FnMut(Self::Item) -> bool,
268 {
269 wrap_either!(&mut self.inner => .position(predicate))
270 }
271}
272
273impl<L, R> DoubleEndedIterator for IterEither<L, R>
274where
275 L: DoubleEndedIterator,
276 R: DoubleEndedIterator,
277{
278 fn next_back(&mut self) -> Option<Self::Item> {
279 Some(map_either!(self.inner, ref mut inner => inner.next_back()?))
280 }
281
282 // TODO(MSRV): This was stabilized in Rust 1.37
283 // fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
284 // Some(map_either!(self.inner, ref mut inner => inner.nth_back(n)?))
285 // }
286
287 fn rfold<Acc, G>(self, init: Acc, f: G) -> Acc
288 where
289 G: FnMut(Acc, Self::Item) -> Acc,
290 {
291 wrap_either!(self.inner => .rfold(init, f))
292 }
293
294 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
295 where
296 P: FnMut(&Self::Item) -> bool,
297 {
298 wrap_either!(&mut self.inner => .rfind(predicate))
299 }
300}
301
302impl<L, R> ExactSizeIterator for IterEither<L, R>
303where
304 L: ExactSizeIterator,
305 R: ExactSizeIterator,
306{
307 fn len(&self) -> usize {
308 for_both!(self.inner, ref inner => inner.len())
309 }
310}
311
312impl<L, R> iter::FusedIterator for IterEither<L, R>
313where
314 L: iter::FusedIterator,
315 R: iter::FusedIterator,
316{
317}
318