From ad5cc9645a5c3de2811eed1b2c6643f27f06764a 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 958bcc124..3a5d80326 100644 --- a/benches/specializations.rs +++ b/benches/specializations.rs @@ -648,6 +648,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 e757837b7..095b08918 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -1041,6 +1041,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 cdc51fb23..ff3d5c19b 100644 --- a/tests/specializations.rs +++ b/tests/specializations.rs @@ -453,7 +453,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