itertools/
process_results_impl.rs1#[cfg(doc)]
2use crate::Itertools;
3
4#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
10#[derive(Debug)]
11pub struct ProcessResults<'a, I, E: 'a> {
12 error: &'a mut Result<(), E>,
13 iter: I,
14}
15
16impl<I, E> ProcessResults<'_, I, E> {
17 #[inline(always)]
18 fn next_body<T>(&mut self, item: Option<Result<T, E>>) -> Option<T> {
19 match item {
20 Some(Ok(x)) => Some(x),
21 Some(Err(e)) => {
22 *self.error = Err(e);
23 None
24 }
25 None => None,
26 }
27 }
28}
29
30impl<I, T, E> Iterator for ProcessResults<'_, I, E>
31where
32 I: Iterator<Item = Result<T, E>>,
33{
34 type Item = T;
35
36 fn next(&mut self) -> Option<Self::Item> {
37 let item = self.iter.next();
38 self.next_body(item)
39 }
40
41 fn size_hint(&self) -> (usize, Option<usize>) {
42 (0, self.iter.size_hint().1)
43 }
44
45 fn fold<B, F>(mut self, init: B, mut f: F) -> B
46 where
47 Self: Sized,
48 F: FnMut(B, Self::Item) -> B,
49 {
50 let error = self.error;
51 self.iter
52 .try_fold(init, |acc, opt| match opt {
53 Ok(x) => Ok(f(acc, x)),
54 Err(e) => {
55 *error = Err(e);
56 Err(acc)
57 }
58 })
59 .unwrap_or_else(|e| e)
60 }
61}
62
63impl<I, T, E> DoubleEndedIterator for ProcessResults<'_, I, E>
64where
65 I: Iterator<Item = Result<T, E>>,
66 I: DoubleEndedIterator,
67{
68 fn next_back(&mut self) -> Option<Self::Item> {
69 let item = self.iter.next_back();
70 self.next_body(item)
71 }
72
73 fn rfold<B, F>(mut self, init: B, mut f: F) -> B
74 where
75 F: FnMut(B, Self::Item) -> B,
76 {
77 let error = self.error;
78 self.iter
79 .try_rfold(init, |acc, opt| match opt {
80 Ok(x) => Ok(f(acc, x)),
81 Err(e) => {
82 *error = Err(e);
83 Err(acc)
84 }
85 })
86 .unwrap_or_else(|e| e)
87 }
88}
89
90pub fn process_results<I, F, T, E, R>(iterable: I, processor: F) -> Result<R, E>
95where
96 I: IntoIterator<Item = Result<T, E>>,
97 F: FnOnce(ProcessResults<I::IntoIter, E>) -> R,
98{
99 let iter = iterable.into_iter();
100 let mut error = Ok(());
101
102 let result = processor(ProcessResults {
103 error: &mut error,
104 iter,
105 });
106
107 error.map(|_| result)
108}