use core::task::{Context, Poll};
use crate::backend::{Format, FormatDecode};
use crate::io;
pub enum StartDecodeStatus<Dta, Dec, Err> {
Fini(Dta),
Pending(Dec),
Error(Err),
}
impl<Dta, Dec, Err> StartDecodeStatus<Dta, Dec, Err> {
#[inline(always)]
pub fn bimap<Fdta, Gdec, F, G>(self, f: F, g: G) -> StartDecodeStatus<Fdta, Gdec, Err>
where
F: FnOnce(Dta) -> Fdta,
G: FnOnce(Dec) -> Gdec,
{
match self {
Self::Fini (dta) => StartDecodeStatus::Fini (f(dta)),
Self::Pending(dec) => StartDecodeStatus::Pending(g(dec)),
Self::Error (err) => StartDecodeStatus::Error (err),
}
}
#[inline(always)]
pub fn and_then<Fdta, Gdec, F, G>(self, f: F, g: G) -> StartDecodeStatus<Fdta, Gdec, Err>
where
F: FnOnce(Dta) -> StartDecodeStatus<Fdta, Gdec, Err>,
G: FnOnce(Dec) -> Gdec,
{
match self {
Self::Fini (dta) => f(dta),
Self::Pending(dec) => StartDecodeStatus::Pending(g(dec)),
Self::Error (err) => StartDecodeStatus::Error (err),
}
}
}
impl<Dta, Dec, Err> From<Dta> for StartDecodeStatus<Dta, Dec, Err> {
#[inline(always)]
fn from(data: Dta) -> Self {
StartDecodeStatus::Fini(data)
}
}
impl<Dta, Dec, Err> From<Result<Dta, Err>> for StartDecodeStatus<Dta, Dec, Err> {
#[inline(always)]
fn from(result: Result<Dta, Err>) -> Self {
match result {
Ok(o) => StartDecodeStatus::Fini(o),
Err(e) => StartDecodeStatus::Error(e),
}
}
}
pub enum PollDecodeStatus<Dta, Err> {
Fini(Dta),
Pending,
Error(Err),
}
impl<Dta, Err> PollDecodeStatus<Dta, Err> {
#[inline(always)]
pub fn map<F, D>(self, f: F) -> PollDecodeStatus<D, Err>
where
F: FnOnce(Dta) -> D
{
match self {
PollDecodeStatus::Fini(d) => PollDecodeStatus::Fini(f(d)),
PollDecodeStatus::Pending => PollDecodeStatus::Pending,
PollDecodeStatus::Error(e) => PollDecodeStatus::Error(e),
}
}
#[inline(always)]
pub fn map_err<F, E>(self, f: F) -> PollDecodeStatus<Dta, E>
where
F: FnOnce(Err) -> E
{
match self {
PollDecodeStatus::Fini(d) => PollDecodeStatus::Fini(d),
PollDecodeStatus::Pending => PollDecodeStatus::Pending,
PollDecodeStatus::Error(e) => PollDecodeStatus::Error(f(e)),
}
}
#[inline(always)]
pub fn and_then<F, D>(self, f: F) -> PollDecodeStatus<D, Err>
where
F: FnOnce(Dta) -> PollDecodeStatus<D, Err>
{
match self {
PollDecodeStatus::Fini(d) => f(d),
PollDecodeStatus::Pending => PollDecodeStatus::Pending,
PollDecodeStatus::Error(e) => PollDecodeStatus::Error(e),
}
}
#[inline(always)]
pub fn lift<P>(self, pend: P) -> StartDecodeStatus<Dta, P, Err>
{
match self {
PollDecodeStatus::Fini(d) => StartDecodeStatus::Fini(d),
PollDecodeStatus::Pending => StartDecodeStatus::Pending(pend),
PollDecodeStatus::Error(e) => StartDecodeStatus::Error(e),
}
}
}
impl<Dta, Err> From<Dta> for PollDecodeStatus<Dta, Err> {
#[inline(always)]
fn from(data: Dta) -> Self {
PollDecodeStatus::Fini(data)
}
}
impl<Dta, Err> From<Result<Dta, Err>> for PollDecodeStatus<Dta, Err> {
#[inline(always)]
fn from(result: Result<Dta, Err>) -> Self {
match result {
Ok(o) => PollDecodeStatus::Fini(o),
Err(e) => PollDecodeStatus::Error(e),
}
}
}
impl<Dta, Err> From<PollDecodeStatus<Dta, Err>> for Poll<Result<Dta, Err>> {
#[inline(always)]
fn from(status: PollDecodeStatus<Dta, Err>) -> Self {
match status {
PollDecodeStatus::Fini(d) => Poll::Ready(Ok(d)),
PollDecodeStatus::Pending => Poll::Pending,
PollDecodeStatus::Error(e) => Poll::Ready(Err(e)),
}
}
}
pub trait Decode: Sized {
type Format: FormatDecode;
type Data;
fn init() -> Self;
fn start_decode<R>(format: &Self::Format, reader: &mut R, cx: &mut Context<'_>) -> StartDecodeStatus<Self::Data, Self, <<Self as Decode>::Format as Format>::Error>
where
R: io::AsyncBufRead + Unpin,
{
let mut dec = Self::init();
dec.poll_decode(format, reader, cx)
.lift(dec)
}
fn poll_decode<R>(&mut self, format: &Self::Format, reader: &mut R, cx: &mut Context<'_>) -> PollDecodeStatus<Self::Data, <<Self as Decode>::Format as Format>::Error>
where
R: io::AsyncBufRead + Unpin,
;
}