diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2020-02-21 18:10:13 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2020-02-21 18:10:13 +0100 |
commit | 20e204905578d943f8fadf5a1770483e97ed4d3c (patch) | |
tree | 2bf56d186b3666f0014dff48f07ab5e1f39a0439 | |
parent | 99fbd1cd76ff8d1ef34202169561d8804bff9240 (diff) |
WIP: Add Skip extension where predicate can fail
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/skip.rs | 87 |
2 files changed, 89 insertions, 0 deletions
@@ -206,6 +206,7 @@ pub mod oks; pub mod onerr; pub mod onok; pub mod prelude; +pub mod skip; pub mod unwrap; mod util; pub mod while_ok; @@ -221,6 +222,7 @@ pub use ok_or_else::{ResultOptionExt, IterInnerOkOrElse}; pub use oks::GetOks; pub use onerr::OnErrDo; pub use onok::OnOkDo; +pub use skip::{SkipWhileMap, SkipWhileMapOk}; pub use unwrap::UnwrapWithExt; pub use util::{GetErr, GetOk, Process}; pub use while_ok::WhileOk; diff --git a/src/skip.rs b/src/skip.rs new file mode 100644 index 0000000..bbf0bb6 --- /dev/null +++ b/src/skip.rs @@ -0,0 +1,87 @@ +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// + + +pub trait SkipWhileMap<O, E>: Sized { + + /// Skip Elements while Ok(true) is returned. + /// + /// Same as Iterator::skip_while, but the predicate function is allowed to return an Err(E), + /// which is then injected into the Iteration. + fn skip_while_map<F>(self, F) -> SkipWhileMapOk<Self, F, O, E> + where + F: FnMut(&O) -> Result<bool, E>; +} + +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +pub struct SkipWhileMapOk<I, F, O, E> + where + F: FnMut(&O) -> Result<bool, E>, + I: Iterator<Item = Result<O, E>> + Sized +{ + iter: I, + func: F +} + + +impl<I, O, E, F> Iterator for SkipWhileMapOk<I, F, O, E> +where + I: Iterator<Item = Result<O, E>>, + F: FnMut(O) -> Result<bool, E>, +{ + type Item = Result<O, E>; + + fn next(&mut self) -> Option<Self::Item> { + loop { + match self.iter.next() { + Some(Ok(x)) => { + match (self.func)(x) { + Ok(true) => return Some(Ok(x)), + Ok(false) => continue, + Err(e) => return Some(Err(e)), + } + } + Some(Err(e)) => return Some(Err(e)), + None => return None, + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + +impl<I, O, E, F> Iterator for SkipWhileMapOk<I, F, O, E> +where + I: Iterator<Item = O>, + F: FnMut(O) -> Result<bool, E>, +{ + type Item = Result<O, E>; + + fn next(&mut self) -> Option<Self::Item> { + loop { + match self.iter.next() { + Some(x) => { + match (self.func)(x) { + Ok(true) => return Some(Ok(x)), + Ok(false) => continue, + Err(e) => return Some(Err(e)), + } + } + Some(Err(e)) => return Some(Err(e)), + None => return None, + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option<usize>) { + self.iter.size_hint() + } +} + |