escvpnet 0.3.3

ESC/VP.net protocol library
Documentation
use async_trait::async_trait;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

use std::{pin::Pin};
pub trait Length {
    const LENGTH: usize;
}
pub trait Decode: Sized + Length + Send {
    type Error: Send;
    fn decode(data: [u8; Self::LENGTH]) -> Result<Self, Self::Error>;
}

pub trait Encode: Length {
    type Error;
    fn encode(self) -> Result<[u8; Self::LENGTH], Self::Error>;
}
#[async_trait]
pub trait DecodeFrom<R>: Sized + Send {
    type Error: Send;
    async fn decode_from(reader: &mut Pin<&mut R>) -> Result<Self, Self::Error>;
}
#[async_trait]
impl<R: AsyncReadExt + Send, D: Decode> DecodeFrom<R> for D
where
    D::Error: From<std::io::Error>,
    [(); Self::LENGTH]:,
{
    type Error = D::Error;
    async fn decode_from(reader: &mut Pin<&mut R>) -> Result<Self, Self::Error> {
        let mut buf = [0; Self::LENGTH];
        reader.read_exact(&mut buf).await?;
        D::decode(buf)
    }
}
#[async_trait]

pub trait EncodeTo<W>: Sized {
    type Error;
    async fn encode_to(self, writer: &mut Pin<&mut W>) -> Result<usize, Self::Error>;
}
#[async_trait]

impl<W: AsyncWriteExt + Send, E: Encode + Send> EncodeTo<W> for E
where
    E::Error: From<std::io::Error> + Send,
    [(); Self::LENGTH]:,
{
    type Error = E::Error;
    async fn encode_to(self, writer: &mut Pin<&mut W>) -> Result<usize, Self::Error> {
        writer.write_all(&self.encode()?).await?;
        Ok(E::LENGTH)
    }
}

impl<const N: usize> Decode for [u8; N] {
    type Error = crate::Error;
    fn decode(data: [u8; Self::LENGTH]) -> Result<Self, Self::Error> {
        Ok(data[..N].try_into().unwrap())
    }
}

impl<T: Decode, const N: usize> Length for [T; N] {
    const LENGTH: usize = T::LENGTH * N;
}

#[macro_export]
macro_rules! number_io {
    ($($type: ty),+) => {
        $(

        impl Length for $type {
            const LENGTH: usize = (Self::BITS / 8) as usize;
        }
        impl Decode for $type {
            type Error = $crate::error::Error;
            fn decode(data: [u8; Self::LENGTH]) -> Result<Self, Self::Error> {
                Ok(Self::from_be_bytes(data))
            }
        }
        impl Encode for $type {
            type Error = $crate::error::Error;
            fn encode(self) -> Result<[u8;Self::LENGTH], Self::Error> {
                Ok(self.to_be_bytes())
            }
        }
                )*
    };
}
number_io!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize);