ufotofu 0.12.5

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

use crate::codec_prelude::*;

/// Turns a [`BulkProducer`] of type `P` into a [`Producer`] of [`Decodable`] `T`s.
///
/// ```
/// use ufotofu::codec_prelude::*;
/// use codec::endian::U32BE;
///
/// # pollster::block_on(async{
/// let byte_producer = [0, 0, 1, 2, 0, 0, 0, 17].into_producer();
/// let mut u32_producer = codec::decoder::<_, U32BE>(byte_producer);
///
/// assert_eq!(u32_producer.produce_item().await?, U32BE(258));
/// assert_eq!(u32_producer.produce_item().await?, U32BE(17));
/// assert_eq!(u32_producer.produce_final().await.unwrap(), ());
/// # Result::<(), ufotofu::ProduceAtLeastError<(), DecodeError::<(), Infallible, Infallible>>>::Ok(())
/// # });
/// ```
///
/// <br/>Counterpart: the [`encoder`](super::encoder) function.
pub fn decoder<C, T>(consumer: C) -> Decoder<C, T> {
    Decoder::new(consumer)
}

/// A [`Producer`] of [`Decodable`] values of type `T`, decoding from an underlying [`BulkConsumer`] of type `P`.
///
/// See [`decoder`].
///
/// <br/>Counterpart: the [`Encoder`](super::Encoder) type.
pub struct Decoder<P, T> {
    inner: P,
    phantom: PhantomData<T>,
}

impl<P, T> Decoder<P, T> {
    // Creates a new [`Decoder`], decoding from the given `producer`.
    fn new(producer: P) -> Self {
        Self {
            inner: producer,
            phantom: PhantomData,
        }
    }

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

impl<P, T, Symbol> Producer for Decoder<P, T>
where
    P: BulkProducer<Item = Symbol>,
    T: Decodable<Symbol>,
{
    type Item = T;

    type Final = P::Final;

    type Error = DecodeError<P::Final, P::Error, T::ErrorReason>;

    async fn produce(&mut self) -> Result<Either<Self::Item, Self::Final>, Self::Error> {
        if let Right(fin) = self.inner.expose_items_sync(|_| (0, ())).await? {
            return Ok(Right(fin));
        }

        Ok(Left(T::decode(&mut self.inner).await?))
    }

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