Skip to content

Commit

Permalink
mob next [ci-skip] [ci skip] [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
mightyiam committed Jan 15, 2022
1 parent db02884 commit 48bd032
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 55 deletions.
11 changes: 11 additions & 0 deletions src/adaptors/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,17 @@ where
}
}

/// Create a new `EnumerateOk` iterator.
pub fn enumerate_ok<I, T, E>(iter: I) -> EnumerateOk<I>
where
I: Iterator<Item = Result<T, E>>,
{
MapSpecialCase {
iter,
f: MapSpecialCaseFnOk(f),
}
}

/// An iterator adapter to apply `Into` conversion to each element.
///
/// See [`.map_into()`](crate::Itertools::map_into) for more information.
Expand Down
71 changes: 16 additions & 55 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,22 @@ 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.
///
/// ```
/// 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<T, E>(self) -> EnumerateOk<Self>
where Self: Iterator<Item = Result<T, E>> + Sized,
{
adaptors::enumerate_ok(self)
}

/// Return an iterator adaptor that applies the provided closure
/// to every `Result::Ok` value. `Result::Err` values are
/// unchanged.
Expand Down Expand Up @@ -2199,61 +2215,6 @@ pub trait Itertools : Iterator {
Ok(start)
}

/// Fold `Result` values from an iterator.
///
/// Only `Ok` values are folded. If no error is encountered, the folded
/// value is returned inside `Ok`. Otherwise, the operation terminates
/// and returns the first `Err` value it encounters. No iterator elements are
/// consumed after the first error.
///
/// The first accumulator value is the `start` parameter.
/// Each iteration passes the accumulator value and the next value inside `Ok`
/// to the fold function `f` and its return value becomes the new accumulator value.
///
/// For example the sequence *Ok(1), Ok(2), Ok(3)* will result in a
/// computation like this:
///
/// ```ignore
/// let mut accum = start;
/// accum = f(accum, 1);
/// accum = f(accum, 2);
/// accum = f(accum, 3);
/// ```
///
/// With a `start` value of 0 and an addition as folding function,
/// this effectively results in *((0 + 1) + 2) + 3*
///
/// ```
/// use std::ops::Add;
/// use itertools::Itertools;
///
/// let values = [1, 2, -2, -1, 2, 1];
/// assert_eq!(
/// values.iter()
/// .map(Ok::<_, ()>)
/// .fold_ok(0, Add::add),
/// Ok(3)
/// );
/// assert!(
/// values.iter()
/// .map(|&x| if x >= 0 { Ok(x) } else { Err("Negative number") })
/// .fold_ok(0, Add::add)
/// .is_err()
/// );
/// ```
fn enumerate_ok<A, E, B, F>(self) -> Result<B, E>
where Self: Iterator<Item = Result<A, E>>,
F: FnMut(B, A) -> B
{
for elt in self {
match elt {
Ok(v) => start = f(start, v),
Err(u) => return Err(u),
}
}
Ok(start)
}

/// Fold `Option` values from an iterator.
///
/// Only `Some` values are folded. If no `None` is encountered, the folded
Expand Down

0 comments on commit 48bd032

Please sign in to comment.