Skip to content

Commit be65c2e

Browse files
committed
Canonicalize special cases of map (1) Generalize MapInto to MapSpecialCase
1 parent 9769e75 commit be65c2e

File tree

1 file changed

+35
-17
lines changed

1 file changed

+35
-17
lines changed

src/adaptors/mod.rs

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -806,34 +806,51 @@ impl_tuple_combination!(Tuple2Combination Tuple1Combination ; A, A, A ; a);
806806
impl_tuple_combination!(Tuple3Combination Tuple2Combination ; A, A, A, A ; a b);
807807
impl_tuple_combination!(Tuple4Combination Tuple3Combination ; A, A, A, A, A; a b c);
808808

809-
/// An iterator adapter to apply `Into` conversion to each element.
810-
///
811-
/// See [`.map_into()`](../trait.Itertools.html#method.map_into) for more information.
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+
812824
#[derive(Clone)]
813825
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
814-
pub struct MapInto<I, R> {
826+
pub struct MapSpecialCase<I, F> {
815827
iter: I,
816-
_res: PhantomData<R>,
828+
f: F,
817829
}
818830

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+
819836
/// Create a new [`MapInto`](struct.MapInto.html) iterator.
820837
pub fn map_into<I, R>(iter: I) -> MapInto<I, R> {
821-
MapInto {
838+
MapSpecialCase {
822839
iter,
823-
_res: PhantomData,
840+
f: MapSpecialCaseFnInto(PhantomData),
824841
}
825842
}
826843

827-
impl<I, R> Iterator for MapInto<I, R>
844+
impl<I, R> Iterator for MapSpecialCase<I, R>
828845
where I: Iterator,
829-
I::Item: Into<R>,
846+
R: MapSpecialCaseFn<I::Item>,
830847
{
831-
type Item = R;
848+
type Item = R::Out;
832849

833850
fn next(&mut self) -> Option<Self::Item> {
834851
self.iter
835852
.next()
836-
.map(|i| i.into())
853+
.map( |i| self.f.call(i))
837854
}
838855

839856
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -843,25 +860,26 @@ impl<I, R> Iterator for MapInto<I, R>
843860
fn fold<Acc, Fold>(self, init: Acc, mut fold_f: Fold) -> Acc
844861
where Fold: FnMut(Acc, Self::Item) -> Acc,
845862
{
846-
self.iter.fold(init, move |acc, v| fold_f(acc, v.into()))
863+
let mut f = self.f;
864+
self.iter.fold(init, move |acc, v| fold_f(acc, f.call(v)))
847865
}
848866
}
849867

850-
impl<I, R> DoubleEndedIterator for MapInto<I, R>
868+
impl<I, R> DoubleEndedIterator for MapSpecialCase<I, R>
851869
where I: DoubleEndedIterator,
852-
I::Item: Into<R>,
870+
R: MapSpecialCaseFn<I::Item>,
853871
{
854872
fn next_back(&mut self) -> Option<Self::Item> {
855873
self.iter
856874
.next_back()
857-
.map(|i| i.into())
875+
.map(|i| self.f.call(i))
858876
}
859877
}
860878

861-
impl<I, R> ExactSizeIterator for MapInto<I, R>
879+
impl<I, R> ExactSizeIterator for MapSpecialCase<I, R>
862880
where
863881
I: ExactSizeIterator,
864-
I::Item: Into<R>,
882+
R: MapSpecialCaseFn<I::Item>,
865883
{}
866884

867885
/// See [`MapOk`](struct.MapOk.html).

0 commit comments

Comments
 (0)