From 0410bca334bc9e80e4e45a1d9b9e602422aef3a1 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Tue, 20 Jul 2021 20:53:43 +0200 Subject: [PATCH 1/2] Specialize ProcessResults::fold --- src/process_results_impl.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/process_results_impl.rs b/src/process_results_impl.rs index 9da108b15..44308f378 100644 --- a/src/process_results_impl.rs +++ b/src/process_results_impl.rs @@ -30,6 +30,23 @@ impl<'a, I, T, E> Iterator for ProcessResults<'a, I, E> fn size_hint(&self) -> (usize, Option) { (0, self.iter.size_hint().1) } + + fn fold(mut self, init: B, mut f: F) -> B + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + let error = self.error; + self.iter + .try_fold(init, |acc, opt| match opt { + Ok(x) => Ok(f(acc, x)), + Err(e) => { + *error = Err(e); + Err(acc) + } + }) + .unwrap_or_else(|e| e) + } } /// “Lift” a function of the values of an iterator so that it can process From bc5ab46c8d86e7800e7e9e4b99c50bcc46233fbb Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Fri, 20 Aug 2021 18:30:00 +0200 Subject: [PATCH 2/2] Add ProcessResults specializations test --- tests/specializations.rs | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/specializations.rs b/tests/specializations.rs index bc337c28e..6a1d0cffb 100644 --- a/tests/specializations.rs +++ b/tests/specializations.rs @@ -98,3 +98,50 @@ quickcheck! { test_specializations(&v.into_iter().map_ok(|u| u.checked_add(1))); } } + +quickcheck! { + fn process_results(v: Vec>) -> () { + helper(v.iter().copied()); + helper(v.iter().copied().filter(Result::is_ok)); + + fn helper(it: impl Iterator> + Clone) { + macro_rules! check_results_specialized { + ($src:expr, |$it:pat| $closure:expr) => { + assert_eq!( + itertools::process_results($src.clone(), |$it| $closure), + itertools::process_results($src.clone(), |i| { + let $it = Unspecialized(i); + $closure + }), + ) + } + } + + check_results_specialized!(it, |i| i.count()); + check_results_specialized!(it, |i| i.last()); + check_results_specialized!(it, |i| i.collect::>()); + check_results_specialized!(it, |i| { + let mut parameters_from_fold = vec![]; + let fold_result = i.fold(vec![], |mut acc, v| { + parameters_from_fold.push((acc.clone(), v.clone())); + acc.push(v); + acc + }); + (parameters_from_fold, fold_result) + }); + check_results_specialized!(it, |mut i| { + let mut parameters_from_all = vec![]; + let first = i.next(); + let all_result = i.all(|x| { + parameters_from_all.push(x.clone()); + Some(x)==first + }); + (parameters_from_all, all_result) + }); + let size = it.clone().count(); + for n in 0..size + 2 { + check_results_specialized!(it, |mut i| i.nth(n)); + } + } + } +}