From 20e204905578d943f8fadf5a1770483e97ed4d3c Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 21 Feb 2020 18:10:13 +0100 Subject: WIP: Add Skip extension where predicate can fail Signed-off-by: Matthias Beyer --- src/lib.rs | 2 ++ src/skip.rs | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/skip.rs diff --git a/src/lib.rs b/src/lib.rs index e9ba2f3..1969e17 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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: 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(self, F) -> SkipWhileMapOk + where + F: FnMut(&O) -> Result; +} + +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +pub struct SkipWhileMapOk + where + F: FnMut(&O) -> Result, + I: Iterator> + Sized +{ + iter: I, + func: F +} + + +impl Iterator for SkipWhileMapOk +where + I: Iterator>, + F: FnMut(O) -> Result, +{ + type Item = Result; + + fn next(&mut self) -> Option { + 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) { + self.iter.size_hint() + } +} + +impl Iterator for SkipWhileMapOk +where + I: Iterator, + F: FnMut(O) -> Result, +{ + type Item = Result; + + fn next(&mut self) -> Option { + 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) { + self.iter.size_hint() + } +} + -- cgit v1.2.3