tamer: iter::trip::TrippableIterator: New trait

This provides convenience methods atop of the already-existing
functions.  These are a bit more ergonomic since they (a) remove a variable
and its generics and (b) are conveniently suggested via LSP (with
e.g. rust-analyzer) if the iterator is of the right type, even if the trait
is not yet imported.  This should help with discoverability as well.
main
Mike Gerwitz 2021-11-05 16:51:02 -04:00
parent 90e3e94c0a
commit 3140279f04
2 changed files with 52 additions and 3 deletions

View File

@ -65,15 +65,17 @@
//! [`into_iter_while_ok`],
//! depending on whether ownership of the source iterator needs to be
//! retained.
//! The [`TrippableIterator`] trait also provides convenient methods
//! directly on compatible [`Iterator`]s.
//! Each of those functions provide their own minimal examples,
//! one of which is reproduced here:
//!
//! ```
//! use tamer::iter::with_iter_while_ok;
//! use tamer::iter::TrippableIterator;
//!
//! let mut values = [Ok(0), Err("trip"), Ok(1)].into_iter();
//!
//! let result = with_iter_while_ok(&mut values, |iter| {
//! let result = values.while_ok(|iter| {
//! // First is `Ok`, so it yields. Note that the value is no longer
//! // `Ok`, which liberates our system from handling others' errors.
//! assert_eq!(Some(0), iter.next());
@ -274,4 +276,6 @@ mod trip;
pub trait ResultIterator<T, E> = Iterator<Item = Result<T, E>>;
pub use collect::{TryCollect, TryFromIterator};
pub use trip::{into_iter_while_ok, with_iter_while_ok, TripIter};
pub use trip::{
into_iter_while_ok, with_iter_while_ok, TripIter, TrippableIterator,
};

View File

@ -245,6 +245,51 @@ where
with_iter_while_ok(&mut from.into_iter(), f)
}
/// An [`Iterator`] supporting the [`while_ok`](TrippableIterator::while_ok)
/// and [`into_while_ok`](TrippableIterator::into_while_ok) trip
/// operations.
///
/// For more information,
/// see the [module-level documentation](self).
pub trait TrippableIterator<T, E>
where
Self: Iterator<Item = Result<T, E>> + Sized,
{
/// Given a mutable reference to a
/// [`ResultIterator<T, E>`](ResultIterator),
/// yield a [`TripIter`] that yields the inner `T` value while the
/// iterator yields an [`Ok`] item.
///
/// For more information,
/// see [`with_iter_while_ok`] and the
/// [module-level documentation](super).
fn while_ok<F, U>(&mut self, f: F) -> Result<U, E>
where
F: FnOnce(&mut TripIter<Self, T, E>) -> U,
{
TripIter::with_iter_while_ok(self, f)
}
/// Given an object capable of being converted into a
/// [`ResultIterator<T, E>`](ResultIterator),
/// yield a [`TripIter`] that yields the inner `T` value while the
/// iterator yields an [`Ok`] item.
///
/// For more information,
/// see [`into_iter_while_ok`] and the [module-level documentation](super).
fn into_while_ok<F, U>(mut self, f: F) -> Result<U, E>
where
F: FnOnce(&mut TripIter<Self, T, E>) -> U,
{
self.while_ok(f)
}
}
impl<T, E, I> TrippableIterator<T, E> for I where
I: Iterator<Item = Result<T, E>> + Sized
{
}
#[cfg(test)]
mod test {
use super::*;