summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2020-02-21 18:10:13 +0100
committerMatthias Beyer <mail@beyermatthias.de>2020-02-21 18:10:13 +0100
commit20e204905578d943f8fadf5a1770483e97ed4d3c (patch)
tree2bf56d186b3666f0014dff48f07ab5e1f39a0439
parent99fbd1cd76ff8d1ef34202169561d8804bff9240 (diff)
WIP: Add Skip extension where predicate can fail
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--src/lib.rs2
-rw-r--r--src/skip.rs87
2 files changed, 89 insertions, 0 deletions
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<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()
+ }
+}
+