ufotofu 0.12.2

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

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

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

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

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

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

    type Final = C::Final;

    type Error = C::Error;

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

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