ufotofu 0.10.1

Abstractions for lazily consuming and producing sequences
Documentation
use core::fmt;
use core::marker::PhantomData;

use crate::prelude::*;

/// A consumer wrapper which passes items through a function before forwarding them to the wrapped consumer.
///
/// Use the `AsRef<C>` and `AsMut<C>` impls to access the wrapped consumer.
///
/// Created via [`ConsumerExt::to_map_item`].
///
/// <br/>Counterpart: the [producer::MapItem] type.
pub struct MapItem<C, Fun, NewItem> {
    inner: C,
    fun: Fun,
    phantom: PhantomData<NewItem>,
}

impl<C, Fun, NewItem> fmt::Debug for MapItem<C, Fun, NewItem>
where
    C: fmt::Debug,
    Fun: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("MapItem")
            .field("inner", &self.inner)
            .field("fun", &self.fun)
            .finish()
    }
}

impl<C, Fun, NewItem> MapItem<C, Fun, NewItem> {
    pub(crate) fn new(inner: C, fun: Fun) -> Self {
        Self {
            inner,
            fun,
            phantom: PhantomData,
        }
    }

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

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

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

impl<C, Fun, NewItem> Consumer for MapItem<C, Fun, NewItem>
where
    C: Consumer,
    Fun: FnMut(NewItem) -> C::Item,
{
    type Item = NewItem;
    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) => self.inner.consume_item((self.fun)(item)).await,
            Right(fin) => self.inner.consume_final(fin).await,
        }
    }

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

/// A consumer wrapper which passes items through an async function before forwarding them to the wrapped consumer.
///
/// Use the `AsRef<C>` and `AsMut<C>` impls to access the wrapped consumer.
///
/// Created via [`ConsumerExt::to_map_async_item`].
///
/// <br/>Counterpart: the [producer::MapAsyncItem] type.
pub struct MapAsyncItem<C, Fun, NewItem> {
    inner: C,
    fun: Fun,
    phantom: PhantomData<NewItem>,
}

impl<C, Fun, NewItem> fmt::Debug for MapAsyncItem<C, Fun, NewItem>
where
    C: fmt::Debug,
    Fun: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("MapAsyncFinal")
            .field("inner", &self.inner)
            .field("fun", &self.fun)
            .finish()
    }
}

impl<C, Fun, NewItem> MapAsyncItem<C, Fun, NewItem> {
    pub(crate) fn new(inner: C, fun: Fun) -> Self {
        Self {
            inner,
            fun,
            phantom: PhantomData,
        }
    }

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

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

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

impl<C, Fun, NewItem> Consumer for MapAsyncItem<C, Fun, NewItem>
where
    C: Consumer,
    Fun: AsyncFnMut(NewItem) -> C::Item,
{
    type Item = NewItem;
    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) => self.inner.consume_item((self.fun)(item).await).await,
            Right(fin) => self.inner.consume_final(fin).await,
        }
    }

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