ufotofu 0.10.1

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

/// A producer wrapper which changes the items of the wrapped producer, by passing produced items through a function.
///
/// Use the `AsRef<P>` and `AsMut<P>` impls to access the wrapped producer.
///
/// Created via [`ProducerExt::to_map_item`].
///
/// <br/>Counterpart: the [consumer::MapItem] type.
#[derive(Debug)]
pub struct MapItem<P, Fun> {
    inner: P,
    fun: Fun,
}

impl<P, Fun> MapItem<P, Fun> {
    pub(crate) fn new(inner: P, fun: Fun) -> Self {
        Self { inner, fun }
    }

    /// Consumes `self` and returns the wrapped producer.
    pub fn into_inner(self) -> P {
        self.inner
    }
}

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

impl<P, Fun> AsMut<P> for MapItem<P, Fun> {
    fn as_mut(&mut self) -> &mut P {
        &mut self.inner
    }
}

impl<P, Fun, NewItem> Producer for MapItem<P, Fun>
where
    P: Producer,
    Fun: FnMut(P::Item) -> NewItem,
{
    type Item = NewItem;
    type Final = P::Final;
    type Error = P::Error;

    async fn produce(&mut self) -> Result<Either<Self::Item, Self::Final>, Self::Error> {
        Ok(self
            .inner
            .produce()
            .await?
            .map_left(|item| (self.fun)(item)))
    }

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

/// A producer wrapper which changes the items of the wrapped producer, by passing produced items through an async function.
///
/// Use the `AsRef<P>` and `AsMut<P>` impls to access the wrapped producer.
///
/// Created via [`ProducerExt::to_map_async_item`].
///
/// <br/>Counterpart: the [consumer::MapAsyncItem] type.
#[derive(Debug)]

pub struct MapAsyncItem<P, Fun> {
    inner: P,
    fun: Fun,
}

impl<P, Fun> MapAsyncItem<P, Fun> {
    pub(crate) fn new(inner: P, fun: Fun) -> Self {
        Self { inner, fun }
    }

    /// Consumes `self` and returns the wrapped producer.
    pub fn into_inner(self) -> P {
        self.inner
    }
}

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

impl<P, Fun> AsMut<P> for MapAsyncItem<P, Fun> {
    fn as_mut(&mut self) -> &mut P {
        &mut self.inner
    }
}

impl<P, Fun, NewItem> Producer for MapAsyncItem<P, Fun>
where
    P: Producer,
    Fun: AsyncFnMut(P::Item) -> NewItem,
{
    type Item = NewItem;
    type Final = P::Final;
    type Error = P::Error;

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

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