Repository: rust-itertools/itertools
Pull request #948 (2024-05-27 18:03:55)

feat(`FilterOk`): implement `DoubleEndedIterator`
Implemented `DoubleEndedIterator` for `FilterOk`

Refs: #947

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/rust-itertools/itertools/pull/948?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 94.43%. Comparing base [(`6814180`)](https://app.codecov.io/gh/rust-itertools/itertools/commit/68141809aabec2816d3250820c8d6608f3b2293f?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) to head [(`f555d16`)](https://app.codecov.io/gh/rust-itertools/itertools/commit/f555d1618917c59ef3e8f3a217fdea8015f08554?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).
> Report is 97 commits behind head on master.


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master     #948      +/-   ##
==========================================
+ Coverage   94.38%   94.43%   +0.04%     
==========================================
  Files          48       49       +1     
  Lines        6665     7021     +356     
==========================================
+ Hits         6291     6630     +339     
- Misses        374      391      +17     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/rust-itertools/itertools/pull/948?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).

Xenira: Added the `rfold` impl

Patch:
diff --git a/benches/specializations.rs b/benches/specializations.rs
index 18039fc..958bcc1 100644
--- a/benches/specializations.rs
+++ b/benches/specializations.rs
@@ -639,6 +639,7 @@ bench_specializations! {
         v.iter().copied().map_ok(|x| x + 1)
     }
     filter_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 6f5e026..e757837 100644
--- a/src/adaptors/mod.rs
+++ b/src/adaptors/mod.rs
@@ -936,6 +936,30 @@ where
     }
 }
 
+impl<I, F, T, E> DoubleEndedIterator for FilterOk<I, F>
+where
+    I: DoubleEndedIterator<Item = Result<T, E>>,
+    F: FnMut(&T) -> bool,
+{
+    fn next_back(&mut self) -> Option<Self::Item> {
+        let f = &mut self.f;
+        self.iter.rfind(|res| match res {
+            Ok(t) => f(t),
+            _ => true,
+        })
+    }
+
+    fn rfold<Acc, Fold>(self, init: Acc, fold_f: Fold) -> Acc
+    where
+        Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut f = self.f;
+        self.iter
+            .filter(|v| v.as_ref().map(&mut f).unwrap_or(true))
+            .rfold(init, fold_f)
+    }
+}
+
 impl<I, F, T, E> FusedIterator for FilterOk<I, F>
 where
     I: FusedIterator<Item = Result<T, E>>,


Test patch:
diff --git a/tests/specializations.rs b/tests/specializations.rs
index 7123114..cdc51fb 100644
--- a/tests/specializations.rs
+++ b/tests/specializations.rs
@@ -447,7 +447,9 @@ quickcheck! {
     }
 
     fn filter_ok(v: Vec<Result<u8, char>>) -> () {
-        test_specializations(&v.into_iter().filter_ok(|&i| i < 20));
+        let it = v.into_iter().filter_ok(|&i| i < 20);
+        test_specializations(&it);
+        test_double_ended_specializations(&it);
     }
 
     fn filter_map_ok(v: Vec<Result<u8, char>>) -> () {