diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs index 2010f535b..6a57ce566 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -839,6 +839,50 @@ impl_tuple_combination!(Tuple10Combination Tuple9Combination; a b c d e f g h i) impl_tuple_combination!(Tuple11Combination Tuple10Combination; a b c d e f g h i j); impl_tuple_combination!(Tuple12Combination Tuple11Combination; a b c d e f g h i j k); +/// An iterator adapter to enumerate values within a nested `Result::Ok`. +/// +/// See [`.enumerate_ok()`](crate::Itertools::enumerate_ok) for more information. +#[derive(Clone)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +pub struct EnumerateOk { + iter: I, + index: usize +} + +/// Create a new `EnumerateOk` iterator. +pub fn enumerate_ok(iter: I) -> EnumerateOk +where + I: Iterator>, +{ + EnumerateOk { + iter, + index: 0 + } +} + +impl fmt::Debug for EnumerateOk +where + I: fmt::Debug, +{ + debug_fmt_fields!(EnumerateOk, iter); +} + +impl Iterator for EnumerateOk + where I: Iterator>, +{ + type Item = Result<(usize,T),E>; + + fn next(&mut self) -> Option { + self.iter.next().map(|item| { + item.map(|v| { + let index = self.index; + self.index +=1; + (index,v) + }) + }) + } +} + /// An iterator adapter to filter values within a nested `Result::Ok`. /// /// See [`.filter_ok()`](crate::Itertools::filter_ok) for more information. diff --git a/src/lib.rs b/src/lib.rs index df95e19ba..ce7ea77ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -99,6 +99,7 @@ pub mod structs { Batching, MapInto, MapOk, + EnumerateOk, Merge, MergeBy, TakeWhileRef, @@ -846,6 +847,23 @@ pub trait Itertools : Iterator { self.map_ok(f) } + /// Return an iterator adaptor that adds an index to `Result::Ok` + /// values. `Result::Err` values are unchanged. The index is incremented + /// only for `Result::Ok` values. + /// + /// ``` + /// use itertools::Itertools; + /// + /// let input = vec![Ok(41), Err(false), Ok(11)]; + /// let it = input.into_iter().enumerate_ok(); + /// itertools::assert_equal(it, vec![Ok((0, 41)), Err(false), Ok((1, 11))]); + /// ``` + fn enumerate_ok(self) -> EnumerateOk + where Self: Iterator> + Sized, + { + adaptors::enumerate_ok(self) + } + /// Return an iterator adaptor that applies the provided closure /// to every `Result::Ok` value. `Result::Err` values are /// unchanged.