From dd1a88a0fade9d04253d9058aa23b1cdd224be72 Mon Sep 17 00:00:00 2001 From: Xenira <1288524+Xenira@users.noreply.github.com> Date: Mon, 27 May 2024 22:41:20 +0200 Subject: [PATCH] feat(`FilterMapOk`): implement `DoubleEndedIterator` Refs: #947 --- benches/specializations.rs | 1 + src/adaptors/mod.rs | 24 ++++++++++++++++++++++++ tests/specializations.rs | 4 +++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/benches/specializations.rs b/benches/specializations.rs index 18039fc4e..c1230e82a 100644 --- a/benches/specializations.rs +++ b/benches/specializations.rs @@ -647,6 +647,7 @@ bench_specializations! { v.iter().copied().filter_ok(|x| x % 3 == 0) } filter_map_ok { + DoubleEndedIterator { let v = black_box((0_u32..1024) .map(|x| if x % 2 == 1 { Err(x) } else { Ok(x) }) diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs index 6f5e0260e..8de99e343 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -1017,6 +1017,30 @@ where } } +impl DoubleEndedIterator for FilterMapOk +where + I: DoubleEndedIterator>, + F: FnMut(T) -> Option, +{ + fn next_back(&mut self) -> Option { + let f = &mut self.f; + self.iter.by_ref().rev().find_map(|res| match res { + Ok(t) => f(t).map(Ok), + Err(e) => Some(Err(e)), + }) + } + + fn rfold(self, init: Acc, fold_f: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + let mut f = self.f; + self.iter + .filter_map(|v| transpose_result(v.map(&mut f))) + .rfold(init, fold_f) + } +} + impl FusedIterator for FilterMapOk where I: FusedIterator>, diff --git a/tests/specializations.rs b/tests/specializations.rs index 712311472..65f4feb99 100644 --- a/tests/specializations.rs +++ b/tests/specializations.rs @@ -451,7 +451,9 @@ quickcheck! { } fn filter_map_ok(v: Vec>) -> () { - test_specializations(&v.into_iter().filter_map_ok(|i| if i < 20 { Some(i * 2) } else { None })); + let it = v.into_iter().filter_map_ok(|i| if i < 20 { Some(i * 2) } else { None }); + test_specializations(&it); + test_double_ended_specializations(&it); } // `SmallIter2` because `Vec` is too slow and we get bad coverage from a singleton like Option