ufotofu 0.12.5

Abstractions for lazily consuming and producing sequences
Documentation
//! Producer functionality for types implementing the trait [`AsyncFnMut`].
//!
//! Specifically, this module provides a [`ClosureProducer`] type which implements [`Producer`] and wraps any [`AsyncFnMut<Args=(), Output=Result<Either<Item, Final>, Error>>`].
//!
//! <br/>Counterpart: the [`consumer::compat::fn_mut`] module.

use crate::prelude::*;
use core::{marker::PhantomData, ops::AsyncFnMut};

/// A [`Producer`] which [`produces`](Producer::produce) values by evaluating a wrapped [`AsyncFnMut`].
///
/// ```
/// use ufotofu::prelude::*;
/// use ufotofu::{pipe, PipeError};
/// use ufotofu::producer::compat::fn_mut::*;
/// # pollster::block_on(async {
///
/// let mut result = 1u8;
///
/// let mut p: ClosureProducer<_, u8, (), ()> = (async || {
///     result = result.checked_add(result).ok_or(())?;
///     Ok(Left(result))
/// }).into();
///
/// let mut numbers = [0; 3];
///
/// pipe(p, &mut numbers).await?;
///
/// assert_eq!(numbers, [1, 2, 4]);
/// # Ok::<(), PipeError<(), ()>>(())
/// # });
/// ```
///
/// <br/>Counterpart: the [`ClosureConsumer`](consumer::compat::fn_mut::ClosureConsumer) type.
pub struct ClosureProducer<F, Item, Final, Error>
where
    F: AsyncFnMut() -> Result<Either<Item, Final>, Error>,
{
    inner: F,
    item: PhantomData<Item>,
    fin: PhantomData<Final>,
    err: PhantomData<Error>,
}

impl<F, Item, Final, Error> ClosureProducer<F, Item, Final, Error>
where
    F: AsyncFnMut() -> Result<Either<Item, Final>, Error>,
{
    /// Constructs a new `ClosureProducer` from the given [`AsyncFnMut`].
    pub fn new(inner: F) -> Self {
        ClosureProducer {
            inner,
            item: PhantomData,
            fin: PhantomData,
            err: PhantomData,
        }
    }
}

impl<F, Item, Final, Error> From<F> for ClosureProducer<F, Item, Final, Error>
where
    F: AsyncFnMut() -> Result<Either<Item, Final>, Error>,
{
    fn from(value: F) -> Self {
        Self::new(value)
    }
}

impl<F, Item, Final, Error> Producer for ClosureProducer<F, Item, Final, Error>
where
    F: AsyncFnMut() -> Result<Either<Item, Final>, Error>,
{
    type Item = Item;

    type Final = Final;

    type Error = Error;

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

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