use core::task::{Context, Poll};
use crate::backend::{Format, FormatEncode};
use crate::io;
pub enum StartEncodeStatus<Enc, Err> {
Fini,
Pending(Enc),
Error(Err),
}
impl<Enc, Err> StartEncodeStatus<Enc, Err> {
#[inline(always)]
pub fn map_pending<F, E>(self, f: F) -> StartEncodeStatus<E, Err>
where
F: FnOnce(Enc) -> E,
{
match self {
Self::Fini => StartEncodeStatus::Fini,
Self::Pending(enc) => StartEncodeStatus::Pending(f(enc)),
Self::Error(e) => StartEncodeStatus::Error(e),
}
}
}
pub enum PollEncodeStatus<Err> {
Fini,
Pending,
Error(Err),
}
impl<Err> PollEncodeStatus<Err> {
#[inline(always)]
pub fn lift<Enc>(self, enc: Enc) -> StartEncodeStatus<Enc, Err> {
match self {
PollEncodeStatus::Fini => StartEncodeStatus::Fini,
PollEncodeStatus::Pending => StartEncodeStatus::Pending(enc),
PollEncodeStatus::Error(err) => StartEncodeStatus::Error(err),
}
}
#[inline(always)]
pub fn map_err<F, E>(self, f: F) -> PollEncodeStatus<E>
where
F: FnOnce(Err) -> E,
{
match self {
PollEncodeStatus::Fini => PollEncodeStatus::Fini,
PollEncodeStatus::Pending => PollEncodeStatus::Pending,
PollEncodeStatus::Error(err) => PollEncodeStatus::Error(f(err))
}
}
}
impl<Err> From<PollEncodeStatus<Err>> for Poll<Result<(), Err>> {
#[inline(always)]
fn from(status: PollEncodeStatus<Err>) -> Self {
match status {
PollEncodeStatus::Fini => Poll::Ready(Ok(())),
PollEncodeStatus::Pending => Poll::Pending,
PollEncodeStatus::Error(e) => Poll::Ready(Err(e)),
}
}
}
pub trait Encode: Sized {
type Format: FormatEncode;
type Data: ?Sized;
fn init(data: &Self::Data) -> Self;
fn start_encode<W>(format: &Self::Format, writer: &mut W, data: &Self::Data, cx: &mut Context<'_>) -> StartEncodeStatus<Self, <<Self as Encode>::Format as Format>::Error>
where
W: io::AsyncWrite + Unpin,
{
let mut enc = Self::init(data);
enc.poll_encode(format, writer, data, cx)
.lift(enc)
}
fn poll_encode<W>(&mut self, format: &Self::Format, writer: &mut W, data: &Self::Data, cx: &mut Context<'_>) -> PollEncodeStatus<<<Self as Encode>::Format as Format>::Error>
where
W: io::AsyncWrite + Unpin,
;
}