use core::fmt;
use core::marker::PhantomData;
use crate::prelude::*;
pub struct MapFinal<C, Fun, NewFinal> {
inner: C,
fun: Option<Fun>,
phantom: PhantomData<NewFinal>,
}
impl<C, Fun, NewFinal> fmt::Debug for MapFinal<C, Fun, NewFinal>
where
C: fmt::Debug,
Fun: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MapFinal")
.field("inner", &self.inner)
.field("fun", &self.fun)
.finish()
}
}
impl<C, Fun, NewFinal> MapFinal<C, Fun, NewFinal> {
pub(crate) fn new(inner: C, fun: Fun) -> Self {
Self {
inner,
fun: Some(fun),
phantom: PhantomData,
}
}
pub fn into_inner(self) -> C {
self.inner
}
}
impl<C, Fun, NewFinal> AsRef<C> for MapFinal<C, Fun, NewFinal> {
fn as_ref(&self) -> &C {
&self.inner
}
}
impl<C, Fun, NewFinal> AsMut<C> for MapFinal<C, Fun, NewFinal> {
fn as_mut(&mut self) -> &mut C {
&mut self.inner
}
}
impl<C, Fun, NewFinal> Consumer for MapFinal<C, Fun, NewFinal>
where
C: Consumer,
Fun: FnOnce(NewFinal) -> C::Final,
{
type Item = C::Item;
type Final = NewFinal;
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(item).await,
Right(fin) => {
self.inner
.consume_final((self
.fun
.take()
.expect("Must not use a consumer after writing a final value to it"))(
fin,
))
.await
}
}
}
async fn flush(&mut self) -> Result<(), Self::Error> {
self.inner.flush().await
}
}
impl<C, Fun, NewFinal> BulkConsumer for MapFinal<C, Fun, NewFinal>
where
C: BulkConsumer,
Fun: FnOnce(NewFinal) -> C::Final,
{
async fn expose_slots_gracefully<F, R>(&mut self, f: F) -> Result<R, (F, Self::Error)>
where
F: AsyncFnOnce(&mut [Self::Item]) -> (usize, R),
{
self.inner.expose_slots_gracefully(f).await
}
}
pub struct MapAsyncFinal<C, Fun, NewFinal> {
inner: C,
fun: Option<Fun>,
phantom: PhantomData<NewFinal>,
}
impl<C, Fun, NewFinal> fmt::Debug for MapAsyncFinal<C, Fun, NewFinal>
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, NewFinal> MapAsyncFinal<C, Fun, NewFinal> {
pub(crate) fn new(inner: C, fun: Fun) -> Self {
Self {
inner,
fun: Some(fun),
phantom: PhantomData,
}
}
pub fn into_inner(self) -> C {
self.inner
}
}
impl<C, Fun, NewFinal> AsRef<C> for MapAsyncFinal<C, Fun, NewFinal> {
fn as_ref(&self) -> &C {
&self.inner
}
}
impl<C, Fun, NewFinal> AsMut<C> for MapAsyncFinal<C, Fun, NewFinal> {
fn as_mut(&mut self) -> &mut C {
&mut self.inner
}
}
impl<C, Fun, NewFinal> Consumer for MapAsyncFinal<C, Fun, NewFinal>
where
C: Consumer,
Fun: AsyncFnOnce(NewFinal) -> C::Final,
{
type Item = C::Item;
type Final = NewFinal;
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(item).await,
Right(fin) => {
self.inner
.consume_final(
(self
.fun
.take()
.expect("Must not use a consumer after writing a final value to it"))(
fin,
)
.await,
)
.await
}
}
}
async fn flush(&mut self) -> Result<(), Self::Error> {
self.inner.flush().await
}
}
impl<C, Fun, NewFinal> BulkConsumer for MapAsyncFinal<C, Fun, NewFinal>
where
C: BulkConsumer,
Fun: AsyncFnOnce(NewFinal) -> C::Final,
{
async fn expose_slots_gracefully<F, R>(&mut self, f: F) -> Result<R, (F, Self::Error)>
where
F: AsyncFnOnce(&mut [Self::Item]) -> (usize, R),
{
self.inner.expose_slots_gracefully(f).await
}
}