ufotofu 0.12.5

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

/// A (bulk) producer wrapper which changes the error (type) of the wrapped producer, by passing errors through a function.
///
/// Use the `AsRef<P>` and `AsMut<P>` impls to access the wrapped producer.
///
/// Created via [`ProducerExt::to_map_error`].
///
/// <br/>Counterpart: the [consumer::MapError] type.
#[derive(Debug)]

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

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

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

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

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

impl<P, Fun, NewErr> Producer for MapError<P, Fun>
where
    P: Producer,
    Fun: FnOnce(P::Error) -> NewErr,
{
    type Item = P::Item;
    type Final = P::Final;
    type Error = NewErr;

    async fn produce(&mut self) -> Result<Either<Self::Item, Self::Final>, Self::Error> {
        self.inner.produce().await.map_err(|err| {
            (self
                .fun
                .take()
                .expect("Must not use a producer after it emitted an error"))(err)
        })
    }

    async fn slurp(&mut self) -> Result<(), Self::Error> {
        self.inner.slurp().await.map_err(|err| {
            (self
                .fun
                .take()
                .expect("Must not use a producer after it emitted an error"))(err)
        })
    }
}

impl<P, Fun, NewErr> BulkProducer for MapError<P, Fun>
where
    P: BulkProducer,
    Fun: FnOnce(P::Error) -> NewErr,
{
    async fn expose_items_gracefully<F, R>(
        &mut self,
        f: F,
    ) -> Result<Either<R, (F, Self::Final)>, (F, Self::Error)>
    where
        F: AsyncFnOnce(&[Self::Item]) -> (usize, R),
    {
        self.inner.expose_items_gracefully(f).await.map_err(|err| {
            (
                err.0,
                (self
                    .fun
                    .take()
                    .expect("Must not use a producer after it emitted an error"))(
                    err.1
                ),
            )
        })
    }
}

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

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

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

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

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

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

impl<P, Fun, NewErr> Producer for MapAsyncError<P, Fun>
where
    P: Producer,
    Fun: AsyncFnOnce(P::Error) -> NewErr,
{
    type Item = P::Item;
    type Final = P::Final;
    type Error = NewErr;

    async fn produce(&mut self) -> Result<Either<Self::Item, Self::Final>, Self::Error> {
        match self.inner.produce().await {
            Ok(yay) => Ok(yay),
            Err(err) => Err((self
                .fun
                .take()
                .expect("Must not use a producer after it emitted an error"))(
                err
            )
            .await),
        }
    }

    async fn slurp(&mut self) -> Result<(), Self::Error> {
        match self.inner.slurp().await {
            Ok(yay) => Ok(yay),
            Err(err) => Err((self
                .fun
                .take()
                .expect("Must not use a producer after it emitted an error"))(
                err
            )
            .await),
        }
    }
}

impl<P, Fun, NewErr> BulkProducer for MapAsyncError<P, Fun>
where
    P: BulkProducer,
    Fun: AsyncFnOnce(P::Error) -> NewErr,
{
    async fn expose_items_gracefully<F, R>(
        &mut self,
        f: F,
    ) -> Result<Either<R, (F, Self::Final)>, (F, Self::Error)>
    where
        F: AsyncFnOnce(&[Self::Item]) -> (usize, R),
    {
        match self.inner.expose_items_gracefully(f).await {
            Ok(yay) => Ok(yay),
            Err(err) => Err((
                err.0,
                (self
                    .fun
                    .take()
                    .expect("Must not use a producer after it emitted an error"))(
                    err.1
                )
                .await,
            )),
        }
    }
}