diny_test 0.2.1

Test serializer format for the diny framework
Documentation
use core::{pin::Pin, task::{Context, Poll}};
use diny::backend::{self, Encode as _, internal::SequenceLen};
use diny::{buffer, io};
use crate::Formatter as ThisFormat;


type Data = [u8];

pub enum Encoder
{
    Init,
    Len(SequenceLen, <SequenceLen as backend::Encodable>::Encoder<ThisFormat>),
    Cur(buffer::BufferCursor),
    Fini,
}

impl Encoder
{
    fn after_init<W>(format: &ThisFormat, writer: &mut W, data: &Data, cx: &mut Context<'_>) -> backend::StartEncodeStatus<Self, <ThisFormat as backend::Format>::Error>
    where
        W: io::AsyncWrite + Unpin,
    {
        let len: SequenceLen = data.len().into();
        match <SequenceLen as backend::Encodable>::Encoder::<ThisFormat>::start_encode(format, writer, &len, cx) {
            backend::StartEncodeStatus::Fini         => Self::after_len(format, writer, *len, data, cx),
            backend::StartEncodeStatus::Pending(enc) => backend::StartEncodeStatus::Pending(Self::Len(len, enc)),
            backend::StartEncodeStatus::Error(e)     => backend::StartEncodeStatus::Error(e)
        }
    }

    fn after_len<W>(_format: &ThisFormat, writer: &mut W, len: usize, data: &Data, cx: &mut Context<'_>) -> backend::StartEncodeStatus<Self, <ThisFormat as backend::Format>::Error>
    where
        W: io::AsyncWrite + Unpin,
    {
        if len > 0 {
            let mut cur = buffer::BufferCursor::new(data);
            match cur.write_remaining(writer, data, cx) {
                backend::PollEncodeStatus::Fini     => backend::StartEncodeStatus::Fini,
                backend::PollEncodeStatus::Pending  => backend::StartEncodeStatus::Pending(Self::Cur(cur)),
                backend::PollEncodeStatus::Error(e) => backend::StartEncodeStatus::Error(e),
            }
        } else {
            backend::StartEncodeStatus::Fini
        }
    }

    fn poll_cur<W>(_format: &ThisFormat, writer: &mut W, cur: &mut buffer::BufferCursor, data: &Data, cx: &mut Context<'_>) -> backend::PollEncodeStatus<<ThisFormat as backend::Format>::Error>
    where
        W: io::AsyncWrite + Unpin,
    {
        cur.write_remaining(writer, data, cx)
    }
}

impl backend::Encode for Encoder
{
    type Data = Data;
    type Format = ThisFormat;

    fn init(_data: &Self::Data) -> Self {
        Self::Init
    }

    fn start_encode<W>(format: &Self::Format, writer: &mut W, data: &Self::Data, cx: &mut Context<'_>) -> backend::StartEncodeStatus<Self, <Self::Format as backend::Format>::Error>
    where
        W: io::AsyncWrite + Unpin,
    {
        Self::after_init(format, writer, data, cx)
    }

    fn poll_encode<W>(&mut self, format: &Self::Format, writer: &mut W, data: &Self::Data, cx: &mut Context<'_>) -> backend::PollEncodeStatus<<Self::Format as backend::Format>::Error>
    where
        W: io::AsyncWrite + Unpin,
    {
        match self {
            Self::Init          => diny::encode_chain!(*self, Self::start_encode(format, writer, data, cx)),
            Self::Len(len, enc) => diny::encode_poll_chain!(*self, enc.poll_encode(format, writer, len, cx), Self::after_len(format, writer, **len, data, cx)),
            Self::Cur(cur)      => diny::encode_poll_fini!(*self, Self::poll_cur(format, writer, cur, data, cx)),
            Self::Fini          => backend::PollEncodeStatus::Error(<Self::Format as backend::Format>::invalid_input_err()),
        }
    }
}

pub struct SerializeAll<'w, W> {
    format: &'w ThisFormat,
    writer: &'w mut W,
    data: &'w Data,
    encoder: Encoder,
}

pub(crate) fn serialize<'w, W>(format: &'w ThisFormat, writer: &'w mut W, data: &'w Data) -> SerializeAll<'w, W>
where
    W: ::diny::io::AsyncWrite + Unpin,
{
    SerializeAll::new(format, writer, data)
}

impl<'w, W> SerializeAll<'w, W> {
    fn new(format: &'w ThisFormat, writer: &'w mut W, data: &'w Data) -> SerializeAll<'w, W>
    where
        W: ::diny::io::AsyncWrite + Unpin,
    {
        SerializeAll {
            format,
            writer,
            data,
            encoder: Encoder::init(data),
        }
    }
}

impl<'w, W> Unpin for SerializeAll<'w, W> {}

impl<'w, W> core::future::Future for SerializeAll<'w, W>
where
    W: ::diny::io::AsyncWrite + Unpin,
{
    type Output = Result<(), <ThisFormat as backend::Format>::Error>;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let this = &mut *self;
        this.encoder.poll_encode(this.format, this.writer, this.data, cx).into()
    }
}