summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2019-10-25 19:15:53 +0200
committerMatthias Beyer <mail@beyermatthias.de>2019-10-25 21:30:19 +0200
commit2034e2fc14e7c1bc55a01426da48d616ab75d920 (patch)
treebb00737d217752953698bfb179b8134698ded500
parentdc3fa9925a8f6031c9b472bbbb7700e2aaa7404d (diff)
Add enumerate helperenumerate-result
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--src/enumerate.rs107
-rw-r--r--src/lib.rs2
2 files changed, 109 insertions, 0 deletions
diff --git a/src/enumerate.rs b/src/enumerate.rs
new file mode 100644
index 0000000..1b20677
--- /dev/null
+++ b/src/enumerate.rs
@@ -0,0 +1,107 @@
+//
+// 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/.
+//
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum EnumOkConfig {
+ /// Ignore Err(_) when counting
+ IgnoreErr,
+
+ /// Increase counter on Err(_)
+ CountErr,
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum EnumErrConfig {
+ /// Ignore Ok(_) when counting
+ IgnoreOk,
+
+ /// Increase counter on Ok(_)
+ CountOk,
+}
+
+pub trait EnumerateResult<T, E>
+ where Self: Iterator<Item = Result<T, E>> + Sized,
+ T: Sized,
+ E: Sized,
+{
+ fn enumerate_ok(self, config: EnumOkConfig) -> EnumerateOkImpl<Self, T, E>;
+ fn enumerate_err(self, config: EnumErrConfig) -> EnumerateErrImpl<Self, T, E>;
+}
+
+impl<I, T, E> EnumerateResult<T, E> for I
+ where I: Iterator<Item = Result<T, E>> + Sized,
+ T: Sized,
+ E: Sized
+{
+ fn enumerate_ok(self, config: EnumOkConfig) -> EnumerateOkImpl<Self, T, E> {
+ EnumerateOkImpl(self, 0, config)
+ }
+
+ fn enumerate_err(self, config: EnumErrConfig) -> EnumerateErrImpl<Self, T, E> {
+ EnumerateErrImpl(self, 0, config)
+ }
+}
+
+
+pub struct EnumerateOkImpl<I, T, E>(I, usize, EnumOkConfig)
+ where I: Iterator<Item = Result<T, E>> + Sized,
+ T: Sized,
+ E: Sized;
+
+impl<I, T, E> Iterator for EnumerateOkImpl<I, T, E>
+ where I: Iterator<Item = Result<T, E>> + Sized,
+ T: Sized,
+ E: Sized,
+{
+ type Item = Result<(usize, T), E>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next().map(|o| match o {
+ Err(e) => {
+ if self.2 == EnumOkConfig::CountErr {
+ self.1 += 1;
+ }
+ Err(e)
+ },
+
+ Ok(t) => {
+ self.1 += 1;
+ Ok((self.1, t))
+ }
+ })
+ }
+}
+
+
+pub struct EnumerateErrImpl<I, T, E>(I, usize, EnumErrConfig)
+ where I: Iterator<Item = Result<T, E>> + Sized,
+ T: Sized,
+ E: Sized;
+
+impl<I, T, E> Iterator for EnumerateErrImpl<I, T, E>
+ where I: Iterator<Item = Result<T, E>> + Sized,
+ T: Sized,
+ E: Sized,
+{
+ type Item = Result<T, (usize, E)>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next().map(|o| match o {
+ Ok(t) => {
+ if self.2 == EnumErrConfig::CountOk {
+ self.1 += 1;
+ }
+ Ok(t)
+ },
+
+ Err(e) => {
+ self.1 += 1;
+ Err((self.1, e))
+ }
+ })
+ }
+}
+
diff --git a/src/lib.rs b/src/lib.rs
index e9ba2f3..7ec4ce2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -195,6 +195,7 @@
//!
pub mod and_then;
+pub mod enumerate;
pub mod errors;
pub mod filter;
pub mod filter_map;
@@ -211,6 +212,7 @@ mod util;
pub mod while_ok;
pub use and_then::AndThen;
+pub use enumerate::*;
pub use errors::GetErrors;
pub use filter::Filter;
pub use filter_map::FilterMap;