#[cfg(feature = "alloc")]
use alloc::boxed::Box;
use crate::prelude::*;
pub struct IntoConsumerMut<'s, T>(&'s mut [T], usize);
impl<'s, T> Consumer for IntoConsumerMut<'s, T> {
type Item = T;
type Final = Infallible;
type Error = ();
async fn consume(&mut self, val: Either<Self::Item, Self::Final>) -> Result<(), Self::Error> {
match val {
Left(item) => {
if self.1 < self.0.len() {
self.0[self.1] = item;
self.1 += 1;
Ok(())
} else {
Err(())
}
}
Right(_fin) => unreachable!(),
}
}
async fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
impl<'a, T> BulkConsumer for IntoConsumerMut<'a, T> {
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 = self.0.len() - self.1;
if len == 0 {
Err((f, ()))
} else {
let (amount, ret) = f(&mut self.0[self.1..]).await;
self.1 += amount;
Ok(ret)
}
}
}
impl<'s, T> crate::IntoConsumer for &'s mut [T] {
type Item = T;
type Final = Infallible;
type Error = ();
type IntoConsumer = IntoConsumerMut<'s, T>;
fn into_consumer(self) -> Self::IntoConsumer {
IntoConsumerMut(self, 0)
}
}
#[cfg(feature = "alloc")]
pub struct IntoConsumerBoxed<T>(Box<[T]>, usize);
#[cfg(feature = "alloc")]
impl<T> From<IntoConsumerBoxed<T>> for Box<[T]> {
fn from(value: IntoConsumerBoxed<T>) -> Self {
value.0
}
}
#[cfg(feature = "alloc")]
impl<T> Consumer for IntoConsumerBoxed<T> {
type Item = T;
type Final = Infallible;
type Error = ();
async fn consume(&mut self, val: Either<Self::Item, Self::Final>) -> Result<(), Self::Error> {
match val {
Left(item) => {
if self.1 < self.0.len() {
self.0[self.1] = item;
self.1 += 1;
Ok(())
} else {
Err(())
}
}
Right(_fin) => unreachable!(),
}
}
async fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
#[cfg(feature = "alloc")]
impl<T> BulkConsumer for IntoConsumerBoxed<T> {
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 = self.0.len() - self.1;
if len == 0 {
Err((f, ()))
} else {
let (amount, ret) = f(&mut self.0[self.1..]).await;
self.1 += amount;
Ok(ret)
}
}
}
#[cfg(feature = "alloc")]
impl<T> crate::IntoConsumer for Box<[T]> {
type Item = T;
type Final = Infallible;
type Error = ();
type IntoConsumer = IntoConsumerBoxed<T>;
fn into_consumer(self) -> Self::IntoConsumer {
IntoConsumerBoxed(self, 0)
}
}
#[cfg(feature = "alloc")]
pub struct IntoConsumerBoxedMut<'s, T>(&'s mut Box<[T]>, usize);
#[cfg(feature = "alloc")]
impl<'s, T> Consumer for IntoConsumerBoxedMut<'s, T> {
type Item = T;
type Final = Infallible;
type Error = ();
async fn consume(&mut self, val: Either<Self::Item, Self::Final>) -> Result<(), Self::Error> {
match val {
Left(item) => {
if self.1 < self.0.len() {
self.0[self.1] = item;
self.1 += 1;
Ok(())
} else {
Err(())
}
}
Right(_fin) => unreachable!(),
}
}
async fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
#[cfg(feature = "alloc")]
impl<'s, T> BulkConsumer for IntoConsumerBoxedMut<'s, T> {
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 = self.0.len() - self.1;
if len == 0 {
Err((f, ()))
} else {
let (amount, ret) = f(&mut self.0[self.1..]).await;
self.1 += amount;
Ok(ret)
}
}
}
#[cfg(feature = "alloc")]
impl<'s, T> crate::IntoConsumer for &'s mut Box<[T]> {
type Item = T;
type Final = Infallible;
type Error = ();
type IntoConsumer = IntoConsumerBoxedMut<'s, T>;
fn into_consumer(self) -> Self::IntoConsumer {
IntoConsumerBoxedMut(self, 0)
}
}