use core::fmt::Debug;
use crate::prelude::*;
#[derive(Debug)]
pub struct IntoConsumer<T, const N: usize>([T; N], usize);
impl<T, const N: usize> From<IntoConsumer<T, N>> for [T; N] {
fn from(value: IntoConsumer<T, N>) -> Self {
value.0
}
}
impl<T, const N: usize> Consumer for IntoConsumer<T, N> {
type Item = T;
type Final = ();
type Error = ();
async fn consume(&mut self, val: Either<Self::Item, Self::Final>) -> Result<(), Self::Error> {
match val {
Left(item) => {
if self.1 < N {
self.0[self.1] = item;
self.1 += 1;
Ok(())
} else {
Err(())
}
}
Right(()) => Ok(()),
}
}
async fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<T, const N: usize> BulkConsumer for IntoConsumer<T, N> {
async fn expose_slots_gracefully<F, R>(&mut self, f: F) -> Result<R, (F, Self::Error)>
where
F: AsyncFnOnce(&mut [Self::Item]) -> (usize, R),
{
if self.1 == N {
Err((f, ()))
} else {
let (amount, ret) = f(&mut self.0[self.1..]).await;
self.1 += amount;
Ok(ret)
}
}
}
impl<T, const N: usize> crate::IntoConsumer for [T; N] {
type Item = T;
type Final = ();
type Error = ();
type IntoConsumer = IntoConsumer<T, N>;
fn into_consumer(self) -> Self::IntoConsumer {
IntoConsumer(self, 0)
}
}
#[derive(Debug)]
pub struct IntoConsumerMut<'a, T, const N: usize>(&'a mut [T; N], usize);
impl<'a, T, const N: usize> Consumer for IntoConsumerMut<'a, T, N> {
type Item = T;
type Final = ();
type Error = ();
async fn consume(&mut self, val: Either<Self::Item, Self::Final>) -> Result<(), Self::Error> {
match val {
Left(item) => {
if self.1 < N {
self.0[self.1] = item;
self.1 += 1;
Ok(())
} else {
Err(())
}
}
Right(()) => Ok(()),
}
}
async fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<'a, T, const N: usize> BulkConsumer for IntoConsumerMut<'a, T, N> {
async fn expose_slots_gracefully<F, R>(&mut self, f: F) -> Result<R, (F, Self::Error)>
where
F: AsyncFnOnce(&mut [Self::Item]) -> (usize, R),
{
let len = N - self.1;
if len == 0 {
Err((f, ()))
} else {
let (amount, ret) = f(&mut self.0[self.1..]).await;
self.1 += amount;
Ok(ret)
}
}
}
impl<'a, T, const N: usize> crate::IntoConsumer for &'a mut [T; N] {
type Item = T;
type Final = ();
type Error = ();
type IntoConsumer = IntoConsumerMut<'a, T, N>;
fn into_consumer(self) -> Self::IntoConsumer {
IntoConsumerMut(self, 0)
}
}