Skip to content

Commit 356d9b6

Browse files
committed
Move iterator code into a module
1 parent a6e0026 commit 356d9b6

File tree

2 files changed

+256
-256
lines changed

2 files changed

+256
-256
lines changed

src/iterator.rs

+254
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
use super::{for_both, Either, Left, Right};
2+
use core::iter;
3+
4+
impl<L, R> Either<L, R> {
5+
/// Convert the inner value to an iterator.
6+
///
7+
/// ```
8+
/// use either::*;
9+
///
10+
/// let left: Either<_, Vec<u32>> = Left(vec![1, 2, 3, 4, 5]);
11+
/// let mut right: Either<Vec<u32>, _> = Right(vec![]);
12+
/// right.extend(left.into_iter());
13+
/// assert_eq!(right, Right(vec![1, 2, 3, 4, 5]));
14+
/// ```
15+
#[allow(clippy::should_implement_trait)]
16+
pub fn into_iter(self) -> Either<L::IntoIter, R::IntoIter>
17+
where
18+
L: IntoIterator,
19+
R: IntoIterator<Item = L::Item>,
20+
{
21+
match self {
22+
Left(l) => Left(l.into_iter()),
23+
Right(r) => Right(r.into_iter()),
24+
}
25+
}
26+
27+
/// Borrow the inner value as an iterator.
28+
///
29+
/// ```
30+
/// use either::*;
31+
///
32+
/// let left: Either<_, &[u32]> = Left(vec![2, 3]);
33+
/// let mut right: Either<Vec<u32>, _> = Right([4, 5].as_slice());
34+
/// let mut all = vec![1];
35+
/// all.extend(left.iter());
36+
/// all.extend(right.iter());
37+
/// assert_eq!(all, vec![1, 2, 3, 4, 5]);
38+
/// ```
39+
pub fn iter(&self) -> Either<<&L as IntoIterator>::IntoIter, <&R as IntoIterator>::IntoIter>
40+
where
41+
for<'a> &'a L: IntoIterator,
42+
for<'a> &'a R: IntoIterator<Item = <&'a L as IntoIterator>::Item>,
43+
{
44+
self.as_ref().into_iter()
45+
}
46+
47+
/// Mutably borrow the inner value as an iterator.
48+
///
49+
/// ```
50+
/// use either::*;
51+
///
52+
/// let mut left: Either<_, &mut [u32]> = Left(vec![2, 3]);
53+
/// for l in left.iter_mut() {
54+
/// *l *= *l
55+
/// }
56+
/// assert_eq!(left, Left(vec![4, 9]));
57+
///
58+
/// let mut inner = [4, 5];
59+
/// let mut right: Either<Vec<u32>, _> = Right(inner.as_mut_slice());
60+
/// for r in right.iter_mut() {
61+
/// *r *= *r
62+
/// }
63+
/// assert_eq!(inner, [16, 25]);
64+
/// ```
65+
pub fn iter_mut(
66+
&mut self,
67+
) -> Either<<&mut L as IntoIterator>::IntoIter, <&mut R as IntoIterator>::IntoIter>
68+
where
69+
for<'a> &'a mut L: IntoIterator,
70+
for<'a> &'a mut R: IntoIterator<Item = <&'a mut L as IntoIterator>::Item>,
71+
{
72+
self.as_mut().into_iter()
73+
}
74+
75+
/// Factors an `Either` of `Iterator`s to be an `Iterator` of `Either`s
76+
/// ```
77+
/// use either::*;
78+
/// let left: Either<_, Vec<u8>> = Left(&["hello"]);
79+
/// assert_eq!(left.factor_iter().next(), Some(Left(&"hello")));
80+
81+
/// let right: Either<&[&str], _> = Right(vec![0, 1]);
82+
/// assert_eq!(right.factor_iter().collect::<Vec<_>>(), vec![Right(0), Right(1)]);
83+
///
84+
/// ```
85+
// TODO(MSRV): doc(alias) was stabilized in Rust 1.48
86+
// #[doc(alias = "transpose")]
87+
pub fn factor_iter(
88+
self,
89+
) -> Either<
90+
core::iter::Map<L::IntoIter, impl Fn(L::Item) -> Either<L::Item, R::Item>>,
91+
core::iter::Map<R::IntoIter, impl Fn(R::Item) -> Either<L::Item, R::Item>>,
92+
>
93+
where
94+
L: IntoIterator,
95+
R: IntoIterator,
96+
{
97+
self.map_either(
98+
|l| l.into_iter().map(Either::Left),
99+
|r| r.into_iter().map(Either::Right),
100+
)
101+
}
102+
}
103+
104+
impl<L, R, A> Extend<A> for Either<L, R>
105+
where
106+
L: Extend<A>,
107+
R: Extend<A>,
108+
{
109+
fn extend<T>(&mut self, iter: T)
110+
where
111+
T: IntoIterator<Item = A>,
112+
{
113+
for_both!(*self, ref mut inner => inner.extend(iter))
114+
}
115+
}
116+
117+
/// `Either<L, R>` is an iterator if both `L` and `R` are iterators.
118+
impl<L, R> Iterator for Either<L, R>
119+
where
120+
L: Iterator,
121+
R: Iterator<Item = L::Item>,
122+
{
123+
type Item = L::Item;
124+
125+
fn next(&mut self) -> Option<Self::Item> {
126+
for_both!(*self, ref mut inner => inner.next())
127+
}
128+
129+
fn size_hint(&self) -> (usize, Option<usize>) {
130+
for_both!(*self, ref inner => inner.size_hint())
131+
}
132+
133+
fn fold<Acc, G>(self, init: Acc, f: G) -> Acc
134+
where
135+
G: FnMut(Acc, Self::Item) -> Acc,
136+
{
137+
for_both!(self, inner => inner.fold(init, f))
138+
}
139+
140+
fn for_each<F>(self, f: F)
141+
where
142+
F: FnMut(Self::Item),
143+
{
144+
for_both!(self, inner => inner.for_each(f))
145+
}
146+
147+
fn count(self) -> usize {
148+
for_both!(self, inner => inner.count())
149+
}
150+
151+
fn last(self) -> Option<Self::Item> {
152+
for_both!(self, inner => inner.last())
153+
}
154+
155+
fn nth(&mut self, n: usize) -> Option<Self::Item> {
156+
for_both!(*self, ref mut inner => inner.nth(n))
157+
}
158+
159+
fn collect<B>(self) -> B
160+
where
161+
B: iter::FromIterator<Self::Item>,
162+
{
163+
for_both!(self, inner => inner.collect())
164+
}
165+
166+
fn partition<B, F>(self, f: F) -> (B, B)
167+
where
168+
B: Default + Extend<Self::Item>,
169+
F: FnMut(&Self::Item) -> bool,
170+
{
171+
for_both!(self, inner => inner.partition(f))
172+
}
173+
174+
fn all<F>(&mut self, f: F) -> bool
175+
where
176+
F: FnMut(Self::Item) -> bool,
177+
{
178+
for_both!(*self, ref mut inner => inner.all(f))
179+
}
180+
181+
fn any<F>(&mut self, f: F) -> bool
182+
where
183+
F: FnMut(Self::Item) -> bool,
184+
{
185+
for_both!(*self, ref mut inner => inner.any(f))
186+
}
187+
188+
fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
189+
where
190+
P: FnMut(&Self::Item) -> bool,
191+
{
192+
for_both!(*self, ref mut inner => inner.find(predicate))
193+
}
194+
195+
fn find_map<B, F>(&mut self, f: F) -> Option<B>
196+
where
197+
F: FnMut(Self::Item) -> Option<B>,
198+
{
199+
for_both!(*self, ref mut inner => inner.find_map(f))
200+
}
201+
202+
fn position<P>(&mut self, predicate: P) -> Option<usize>
203+
where
204+
P: FnMut(Self::Item) -> bool,
205+
{
206+
for_both!(*self, ref mut inner => inner.position(predicate))
207+
}
208+
}
209+
210+
impl<L, R> DoubleEndedIterator for Either<L, R>
211+
where
212+
L: DoubleEndedIterator,
213+
R: DoubleEndedIterator<Item = L::Item>,
214+
{
215+
fn next_back(&mut self) -> Option<Self::Item> {
216+
for_both!(*self, ref mut inner => inner.next_back())
217+
}
218+
219+
// TODO(MSRV): This was stabilized in Rust 1.37
220+
// fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
221+
// for_both!(*self, ref mut inner => inner.nth_back(n))
222+
// }
223+
224+
fn rfold<Acc, G>(self, init: Acc, f: G) -> Acc
225+
where
226+
G: FnMut(Acc, Self::Item) -> Acc,
227+
{
228+
for_both!(self, inner => inner.rfold(init, f))
229+
}
230+
231+
fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
232+
where
233+
P: FnMut(&Self::Item) -> bool,
234+
{
235+
for_both!(*self, ref mut inner => inner.rfind(predicate))
236+
}
237+
}
238+
239+
impl<L, R> ExactSizeIterator for Either<L, R>
240+
where
241+
L: ExactSizeIterator,
242+
R: ExactSizeIterator<Item = L::Item>,
243+
{
244+
fn len(&self) -> usize {
245+
for_both!(*self, ref inner => inner.len())
246+
}
247+
}
248+
249+
impl<L, R> iter::FusedIterator for Either<L, R>
250+
where
251+
L: iter::FusedIterator,
252+
R: iter::FusedIterator<Item = L::Item>,
253+
{
254+
}

0 commit comments

Comments
 (0)