summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortummychow <tummychow@users.noreply.github.com>2018-03-22 20:14:53 -0700
committertummychow <tummychow@users.noreply.github.com>2018-03-22 20:36:56 -0700
commit0540780fddd59c16e7985f78a9bdfb9efa6a40df (patch)
treed322b2cc9749eaec57817f2c96fabdbf4e99c362
parentfe16ae36af845c8bf49c2a27f45271a68f8981d0 (diff)
add takewhileok iterator adapterstack-adapter
this is like takewhile, but it only works on iterators of results, and it automatically passes through error values. this way, you can collect the iterator of results into a single result, preserving any inner error, while ergonomically terminating the iterator on an undesired non-error value.
-rw-r--r--src/stack.rs41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/stack.rs b/src/stack.rs
index e8faa77..40b3f25 100644
--- a/src/stack.rs
+++ b/src/stack.rs
@@ -75,6 +75,47 @@ pub fn working_stack<'repo>(
Ok(ret)
}
+struct TakeWhileOk<I, T, E, P>
+where
+ I: Iterator<Item = Result<T, E>>,
+{
+ iter: I,
+ predicate: P,
+}
+
+impl<I, T, E, P> TakeWhileOk<I, T, E, P>
+where
+ I: Iterator<Item = Result<T, E>>,
+ P: FnMut(&T) -> bool,
+{
+ fn new<J>(iter: J, pred: P) -> TakeWhileOk<I, T, E, P>
+ where
+ J: IntoIterator<Item = Result<T, E>, IntoIter = I>,
+ {
+ TakeWhileOk {
+ iter: iter.into_iter(),
+ predicate: pred,
+ }
+ }
+}
+
+impl<I, T, E, P> Iterator for TakeWhileOk<I, T, E, P>
+where
+ I: Iterator<Item = Result<T, E>>,
+ P: FnMut(&T) -> bool,
+{
+ type Item = I::Item;
+ fn next(&mut self) -> Option<Self::Item> {
+ let next = self.iter.next();
+ if let Some(Ok(ref v)) = next {
+ if !(self.predicate)(v) {
+ return None;
+ }
+ }
+ next
+ }
+}
+
#[cfg(test)]
mod tests {
extern crate tempdir;