Skip to content

Commit 9346100

Browse files
committed
Canonicalize special cases of map (5) move to own module
1 parent 9105061 commit 9346100

File tree

2 files changed

+122
-116
lines changed

2 files changed

+122
-116
lines changed

src/adaptors/map.rs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
use std::iter::FromIterator;
2+
use std::marker::PhantomData;
3+
4+
#[derive(Clone)]
5+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
6+
pub struct MapSpecialCase<I, F> {
7+
iter: I,
8+
f: F,
9+
}
10+
11+
pub trait MapSpecialCaseFn<T> {
12+
type Out;
13+
fn call(&mut self, t: T) -> Self::Out;
14+
}
15+
16+
impl<I, R> Iterator for MapSpecialCase<I, R>
17+
where
18+
I: Iterator,
19+
R: MapSpecialCaseFn<I::Item>,
20+
{
21+
type Item = R::Out;
22+
23+
fn next(&mut self) -> Option<Self::Item> {
24+
self.iter.next().map(|i| self.f.call(i))
25+
}
26+
27+
fn size_hint(&self) -> (usize, Option<usize>) {
28+
self.iter.size_hint()
29+
}
30+
31+
fn fold<Acc, Fold>(self, init: Acc, mut fold_f: Fold) -> Acc
32+
where
33+
Fold: FnMut(Acc, Self::Item) -> Acc,
34+
{
35+
let mut f = self.f;
36+
self.iter.fold(init, move |acc, v| fold_f(acc, f.call(v)))
37+
}
38+
39+
fn collect<C>(self) -> C
40+
where
41+
C: FromIterator<Self::Item>,
42+
{
43+
let mut f = self.f;
44+
self.iter.map(move |v| f.call(v)).collect()
45+
}
46+
}
47+
48+
impl<I, R> DoubleEndedIterator for MapSpecialCase<I, R>
49+
where
50+
I: DoubleEndedIterator,
51+
R: MapSpecialCaseFn<I::Item>,
52+
{
53+
fn next_back(&mut self) -> Option<Self::Item> {
54+
self.iter.next_back().map(|i| self.f.call(i))
55+
}
56+
}
57+
58+
impl<I, R> ExactSizeIterator for MapSpecialCase<I, R>
59+
where
60+
I: ExactSizeIterator,
61+
R: MapSpecialCaseFn<I::Item>,
62+
{
63+
}
64+
65+
/// An iterator adapter to apply a transformation within a nested `Result::Ok`.
66+
///
67+
/// See [`.map_ok()`](../trait.Itertools.html#method.map_ok) for more information.
68+
pub type MapOk<I, F> = MapSpecialCase<I, MapSpecialCaseFnOk<F>>;
69+
70+
/// See [`MapOk`](struct.MapOk.html).
71+
#[deprecated(note = "Use MapOk instead", since = "0.10")]
72+
pub type MapResults<I, F> = MapOk<I, F>;
73+
74+
impl<F, T, U, E> MapSpecialCaseFn<Result<T, E>> for MapSpecialCaseFnOk<F>
75+
where
76+
F: FnMut(T) -> U,
77+
{
78+
type Out = Result<U, E>;
79+
fn call(&mut self, t: Result<T, E>) -> Self::Out {
80+
t.map(|v| self.0(v))
81+
}
82+
}
83+
84+
#[derive(Clone)]
85+
pub struct MapSpecialCaseFnOk<F>(F);
86+
87+
/// Create a new `MapOk` iterator.
88+
pub fn map_ok<I, F, T, U, E>(iter: I, f: F) -> MapOk<I, F>
89+
where
90+
I: Iterator<Item = Result<T, E>>,
91+
F: FnMut(T) -> U,
92+
{
93+
MapSpecialCase {
94+
iter,
95+
f: MapSpecialCaseFnOk(f),
96+
}
97+
}
98+
99+
/// An iterator adapter to apply `Into` conversion to each element.
100+
///
101+
/// See [`.map_into()`](../trait.Itertools.html#method.map_into) for more information.
102+
pub type MapInto<I, R> = MapSpecialCase<I, MapSpecialCaseFnInto<R>>;
103+
104+
impl<T: Into<U>, U> MapSpecialCaseFn<T> for MapSpecialCaseFnInto<U> {
105+
type Out = U;
106+
fn call(&mut self, t: T) -> Self::Out {
107+
t.into()
108+
}
109+
}
110+
111+
#[derive(Clone)]
112+
pub struct MapSpecialCaseFnInto<U>(PhantomData<U>);
113+
114+
/// Create a new [`MapInto`](struct.MapInto.html) iterator.
115+
pub fn map_into<I, R>(iter: I) -> MapInto<I, R> {
116+
MapSpecialCase {
117+
iter,
118+
f: MapSpecialCaseFnInto(PhantomData),
119+
}
120+
}

src/adaptors/mod.rs

Lines changed: 2 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
//! except according to those terms.
66
77
mod coalesce;
8+
mod map;
89
mod multi_product;
910
pub use self::coalesce::*;
11+
pub use self::map::*;
1012
#[cfg(feature = "use_std")]
1113
pub use self::multi_product::*;
1214

@@ -806,122 +808,6 @@ impl_tuple_combination!(Tuple2Combination Tuple1Combination ; A, A, A ; a);
806808
impl_tuple_combination!(Tuple3Combination Tuple2Combination ; A, A, A, A ; a b);
807809
impl_tuple_combination!(Tuple4Combination Tuple3Combination ; A, A, A, A, A; a b c);
808810

809-
pub trait MapSpecialCaseFn<T> {
810-
type Out;
811-
fn call(&mut self, t: T) -> Self::Out;
812-
}
813-
814-
#[derive(Clone)]
815-
pub struct MapSpecialCaseFnInto<U>(PhantomData<U>);
816-
817-
impl<T: Into<U>, U> MapSpecialCaseFn<T> for MapSpecialCaseFnInto<U> {
818-
type Out = U;
819-
fn call(&mut self, t: T) -> Self::Out {
820-
t.into()
821-
}
822-
}
823-
824-
#[derive(Clone)]
825-
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
826-
pub struct MapSpecialCase<I, F> {
827-
iter: I,
828-
f: F,
829-
}
830-
831-
/// An iterator adapter to apply `Into` conversion to each element.
832-
///
833-
/// See [`.map_into()`](../trait.Itertools.html#method.map_into) for more information.
834-
pub type MapInto<I, R> = MapSpecialCase<I, MapSpecialCaseFnInto<R>>;
835-
836-
/// Create a new [`MapInto`](struct.MapInto.html) iterator.
837-
pub fn map_into<I, R>(iter: I) -> MapInto<I, R> {
838-
MapSpecialCase {
839-
iter,
840-
f: MapSpecialCaseFnInto(PhantomData),
841-
}
842-
}
843-
844-
impl<I, R> Iterator for MapSpecialCase<I, R>
845-
where I: Iterator,
846-
R: MapSpecialCaseFn<I::Item>,
847-
{
848-
type Item = R::Out;
849-
850-
fn next(&mut self) -> Option<Self::Item> {
851-
self.iter
852-
.next()
853-
.map( |i| self.f.call(i))
854-
}
855-
856-
fn size_hint(&self) -> (usize, Option<usize>) {
857-
self.iter.size_hint()
858-
}
859-
860-
fn fold<Acc, Fold>(self, init: Acc, mut fold_f: Fold) -> Acc
861-
where Fold: FnMut(Acc, Self::Item) -> Acc,
862-
{
863-
let mut f = self.f;
864-
self.iter.fold(init, move |acc, v| fold_f(acc, f.call(v)))
865-
}
866-
867-
fn collect<C>(self) -> C
868-
where C: FromIterator<Self::Item>
869-
{
870-
let mut f = self.f;
871-
self.iter.map(move |v| f.call(v)).collect()
872-
}
873-
}
874-
875-
impl<I, R> DoubleEndedIterator for MapSpecialCase<I, R>
876-
where I: DoubleEndedIterator,
877-
R: MapSpecialCaseFn<I::Item>,
878-
{
879-
fn next_back(&mut self) -> Option<Self::Item> {
880-
self.iter
881-
.next_back()
882-
.map(|i| self.f.call(i))
883-
}
884-
}
885-
886-
impl<I, R> ExactSizeIterator for MapSpecialCase<I, R>
887-
where
888-
I: ExactSizeIterator,
889-
R: MapSpecialCaseFn<I::Item>,
890-
{}
891-
892-
/// See [`MapOk`](struct.MapOk.html).
893-
#[deprecated(note="Use MapOk instead", since="0.10")]
894-
pub type MapResults<I, F> = MapOk<I, F>;
895-
896-
#[derive(Clone)]
897-
pub struct MapSpecialCaseFnOk<F>(F);
898-
899-
impl<F, T, U, E> MapSpecialCaseFn<Result<T, E>> for MapSpecialCaseFnOk<F>
900-
where
901-
F: FnMut(T)->U
902-
{
903-
type Out = Result<U, E>;
904-
fn call(&mut self, t: Result<T, E>) -> Self::Out {
905-
t.map(|v| self.0(v))
906-
}
907-
}
908-
909-
/// An iterator adapter to apply a transformation within a nested `Result::Ok`.
910-
///
911-
/// See [`.map_ok()`](../trait.Itertools.html#method.map_ok) for more information.
912-
pub type MapOk<I, F> = MapSpecialCase<I, MapSpecialCaseFnOk<F>>;
913-
914-
/// Create a new `MapOk` iterator.
915-
pub fn map_ok<I, F, T, U, E>(iter: I, f: F) -> MapOk<I, F>
916-
where I: Iterator<Item = Result<T, E>>,
917-
F: FnMut(T) -> U,
918-
{
919-
MapSpecialCase {
920-
iter,
921-
f: MapSpecialCaseFnOk(f),
922-
}
923-
}
924-
925811
/// An iterator adapter to filter values within a nested `Result::Ok`.
926812
///
927813
/// See [`.filter_ok()`](../trait.Itertools.html#method.filter_ok) for more information.

0 commit comments

Comments
 (0)