Skip to content

Commit dd1a88a

Browse files
committed
feat(FilterMapOk): implement DoubleEndedIterator
Refs: rust-itertools#947
1 parent ac8fb03 commit dd1a88a

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

benches/specializations.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ bench_specializations! {
647647
v.iter().copied().filter_ok(|x| x % 3 == 0)
648648
}
649649
filter_map_ok {
650+
DoubleEndedIterator
650651
{
651652
let v = black_box((0_u32..1024)
652653
.map(|x| if x % 2 == 1 { Err(x) } else { Ok(x) })

src/adaptors/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,30 @@ where
10171017
}
10181018
}
10191019

1020+
impl<I, F, T, U, E> DoubleEndedIterator for FilterMapOk<I, F>
1021+
where
1022+
I: DoubleEndedIterator<Item = Result<T, E>>,
1023+
F: FnMut(T) -> Option<U>,
1024+
{
1025+
fn next_back(&mut self) -> Option<Self::Item> {
1026+
let f = &mut self.f;
1027+
self.iter.by_ref().rev().find_map(|res| match res {
1028+
Ok(t) => f(t).map(Ok),
1029+
Err(e) => Some(Err(e)),
1030+
})
1031+
}
1032+
1033+
fn rfold<Acc, Fold>(self, init: Acc, fold_f: Fold) -> Acc
1034+
where
1035+
Fold: FnMut(Acc, Self::Item) -> Acc,
1036+
{
1037+
let mut f = self.f;
1038+
self.iter
1039+
.filter_map(|v| transpose_result(v.map(&mut f)))
1040+
.rfold(init, fold_f)
1041+
}
1042+
}
1043+
10201044
impl<I, F, T, U, E> FusedIterator for FilterMapOk<I, F>
10211045
where
10221046
I: FusedIterator<Item = Result<T, E>>,

tests/specializations.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,9 @@ quickcheck! {
451451
}
452452

453453
fn filter_map_ok(v: Vec<Result<u8, char>>) -> () {
454-
test_specializations(&v.into_iter().filter_map_ok(|i| if i < 20 { Some(i * 2) } else { None }));
454+
let it = v.into_iter().filter_map_ok(|i| if i < 20 { Some(i * 2) } else { None });
455+
test_specializations(&it);
456+
test_double_ended_specializations(&it);
455457
}
456458

457459
// `SmallIter2<u8>` because `Vec<u8>` is too slow and we get bad coverage from a singleton like Option<u8>

0 commit comments

Comments
 (0)