Skip to content

Commit

Permalink
Merge #563
Browse files Browse the repository at this point in the history
563: Specialize ProcessResults::fold r=phimuemue a=SkiFire13

Partially fixes #562. `try_fold` can't be added right now because it requires the unstable `Try` trait.

Co-authored-by: Giacomo Stevanato <giaco.stevanato@gmail.com>
  • Loading branch information
bors[bot] and SkiFire13 committed Aug 20, 2021
2 parents d232918 + bc5ab46 commit b6c99ba
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/process_results_impl.rs
Expand Up @@ -30,6 +30,23 @@ impl<'a, I, T, E> Iterator for ProcessResults<'a, I, E>
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.iter.size_hint().1)
}

fn fold<B, F>(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
Expand Down
47 changes: 47 additions & 0 deletions tests/specializations.rs
Expand Up @@ -104,3 +104,50 @@ quickcheck! {
test_specializations(&v.into_iter().map_ok(|u| u.checked_add(1)));
}
}

quickcheck! {
fn process_results(v: Vec<Result<u8, u8>>) -> () {
helper(v.iter().copied());
helper(v.iter().copied().filter(Result::is_ok));

fn helper(it: impl Iterator<Item = Result<u8, u8>> + 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::<Vec<_>>());
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));
}
}
}
}

0 comments on commit b6c99ba

Please sign in to comment.