ufotofu 0.12.1

Abstractions for lazily consuming and producing sequences
Documentation
use crate::prelude::*;

/// A wrapper for a [`producer`](Producer) which only produces items which meet a given predicate.
///
/// Items producerd by the wrapped producer for which the predicate returns `false` are dropped.
///
/// Use the [`into_inner`](Filter::into_inner) method or [`AsRef<P>`](AsRef) impl to access the wrapped producer.
///
/// Created via the [`ProducerExt::to_filter`] method.
///
/// <br/> Counterpart: the [consumer::Filter] type.
pub struct Filter<P, Pred> {
    inner: P,
    predicate: Pred,
}

impl<P, Pred> Filter<P, Pred>
where
    P: Producer,
    Pred: AsyncFnMut(&P::Item) -> bool,
{
    pub(crate) fn new(inner: P, predicate: Pred) -> Self {
        Filter { inner, predicate }
    }

    /// Retrieves the wrapped [`Producer`], dropping the provided predicate.
    pub fn into_inner(self) -> P {
        self.inner
    }
}

impl<P, Pred> AsRef<P> for Filter<P, Pred> {
    fn as_ref(&self) -> &P {
        &self.inner
    }
}

impl<P, Pred> Producer for Filter<P, Pred>
where
    P: Producer,
    Pred: AsyncFnMut(&P::Item) -> bool,
{
    type Item = P::Item;

    type Final = P::Final;

    type Error = P::Error;

    async fn produce(&mut self) -> Result<Either<Self::Item, Self::Final>, Self::Error> {
        loop {
            match self.inner.produce().await? {
                Left(item) => {
                    if (self.predicate)(&item).await {
                        return Ok(Left(item));
                    }
                }
                Right(fin) => return Ok(Right(fin)),
            }
        }
    }

    async fn slurp(&mut self) -> Result<(), Self::Error> {
        self.inner.slurp().await
    }
}