use crate::Cursor;
use crate::{Buf, BufMut, BufResult};
pub trait Codec<C = ()>: Sized {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, context: C) -> BufResult<()>;
fn decode<R: Buf>(reader: &mut Cursor<R>, context: C) -> BufResult<Self>;
}
impl Codec for u8 {
#[inline]
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
writer.write_u8(*self)
}
#[inline]
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
reader.read_u8()
}
}
impl Codec for u16 {
#[inline]
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
writer.write_u16_be(*self)
}
#[inline]
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
reader.read_u16_be()
}
}
impl Codec for u32 {
#[inline]
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
writer.write_u32_be(*self)
}
#[inline]
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
reader.read_u32_be()
}
}
impl Codec for u64 {
#[inline]
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
writer.write_array(&self.to_be_bytes())
}
#[inline]
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
let bytes = reader.read_array::<8>()?;
Ok(u64::from_be_bytes(bytes))
}
}
impl<const N: usize> Codec for [u8; N] {
#[inline]
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
writer.write_array(self)
}
#[inline]
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
reader.read_array::<N>()
}
}
#[cfg(feature = "alloc")]
impl<T: Codec> Codec for Vec<T> {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: ()) -> BufResult<()> {
for item in self.iter() {
item.encode(writer, ())?;
}
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, _: ()) -> BufResult<Self> {
let mut vec = Vec::new();
while !reader.is_eof() {
vec.push(T::decode(reader, ())?);
}
Ok(vec)
}
}
#[cfg(feature = "alloc")]
impl<T: Codec> Codec<usize> for Vec<T> {
fn encode<W: BufMut>(&self, writer: &mut Cursor<W>, _: usize) -> BufResult<()> {
for item in self.iter() {
item.encode(writer, ())?;
}
Ok(())
}
fn decode<R: Buf>(reader: &mut Cursor<R>, to_decode: usize) -> BufResult<Self> {
let mut vec = Vec::new();
for _ in 0..to_decode {
if reader.is_eof() {
use crate::BufError;
return Err(BufError::OutOfBounds);
}
vec.push(T::decode(reader, ())?);
}
Ok(vec)
}
}