use std::io::{Read, Write};
use crate::Header;
use super::{Error, Result};
pub use bytes::{Buf, BufMut, Bytes, BytesMut};
pub trait Decode: Sized {
fn decode(buf: &mut Bytes) -> Result<Self>;
fn decode_exact(buf: &mut Bytes, size: usize) -> Result<Self> {
if buf.remaining() < size {
return Err(Error::OutOfBounds);
}
let buf = &mut buf.copy_to_bytes(size);
let res = Self::decode(buf)?;
if buf.remaining() > 0 {
return Err(Error::ShortRead);
}
Ok(res)
}
}
pub trait DecodeFrom {
fn decode<T: Decode>(&mut self) -> Result<T>;
fn decode_exact<T: Decode>(&mut self, size: usize) -> Result<T>;
}
pub trait DecodeAtom: Sized {
fn decode_atom(header: &Header, buf: &mut Bytes) -> Result<Self>;
}
pub trait Encode {
fn encode(&self, buf: &mut BytesMut) -> Result<()>;
}
pub trait EncodeTo {
fn encode<T: Encode>(&mut self, v: &T) -> Result<()>;
}
pub trait ReadFrom: Sized {
fn read_from<R: Read>(r: &mut R) -> Result<Self>;
}
pub trait ReadAtom: Sized {
fn read_atom<R: Read>(header: &Header, r: &mut R) -> Result<Self>;
}
pub trait WriteTo {
fn write_to<W: Write>(&self, w: &mut W) -> Result<()>;
}
#[cfg(feature = "tokio")]
pub trait AsyncReadFrom: Sized {
#[allow(async_fn_in_trait)]
async fn read_from<R: tokio::io::AsyncRead + Unpin>(r: &mut R) -> Result<Self>;
}
#[cfg(feature = "tokio")]
pub trait AsyncWriteTo {
#[allow(async_fn_in_trait)]
async fn write_to<W: tokio::io::AsyncWrite + Unpin>(&self, w: &mut W) -> Result<()>;
}
#[cfg(feature = "tokio")]
pub trait AsyncReadAtom: Sized {
#[allow(async_fn_in_trait)]
async fn read_atom<R: tokio::io::AsyncRead + Unpin>(header: &Header, r: &mut R)
-> Result<Self>;
}
impl<T: Encode> WriteTo for T {
fn write_to<W: Write>(&self, w: &mut W) -> Result<()> {
let mut buf = BytesMut::new();
self.encode(&mut buf)?;
Ok(w.write_all(&buf)?)
}
}
#[cfg(feature = "tokio")]
impl<T: Encode> AsyncWriteTo for T {
async fn write_to<W: tokio::io::AsyncWrite + Unpin>(&self, w: &mut W) -> Result<()> {
use tokio::io::AsyncWriteExt;
let mut buf = BytesMut::new();
self.encode(&mut buf)?;
Ok(w.write_all(&buf).await?)
}
}