use heapless::{String, Vec};
use crate::{codec::{Codec, DecodeError, EncodeError}, DecodeBuffer, EncodeBuffer};
#[derive(Copy, Clone)]
pub enum Endian {
Big,
Little,
Host
}
impl Codec<()> for u8 {
fn encode(&self, buf: & mut impl EncodeBuffer, _: ()) -> Result<(), EncodeError> {
buf.push(*self)
}
fn decode(buf: &mut impl DecodeBuffer, _: ()) -> Result<Self, DecodeError> {
buf.read()
}
}
impl Codec<Endian> for i8 {
fn encode(&self, buf: & mut impl EncodeBuffer, _: Endian) -> Result<(), EncodeError> {
buf.push(*self as u8)
}
fn decode(buf: &mut impl DecodeBuffer, _: Endian) -> Result<Self, DecodeError> {
Ok(buf.read()? as i8)
}
}
impl Codec<Endian> for u16 {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;2];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl Codec<Endian> for i16 {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;2];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl Codec<Endian> for u32 {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;4];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl Codec<Endian> for i32 {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;4];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl Codec<Endian> for u64 {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;8];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl Codec<Endian> for i64 {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;8];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl Codec<Endian> for u128 {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;16];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl Codec<Endian> for i128 {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;16];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl Codec<Endian> for usize {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;(usize::BITS / 8) as usize];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl Codec<Endian> for isize {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;(usize::BITS / 8) as usize];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl Codec<Endian> for f32 {
fn encode(&self, buf: &mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;4];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl Codec<Endian> for f64 {
fn encode(&self, buf: &mut impl EncodeBuffer, ctx: Endian) -> Result<(), EncodeError> {
match ctx {
Endian::Big => buf.push_slice(&self.to_be_bytes()),
Endian::Little => buf.push_slice(&self.to_le_bytes()),
Endian::Host => buf.push_slice(&self.to_ne_bytes()),
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: Endian) -> Result<Self, DecodeError> {
let mut slice = [0u8;8];
buf.read_slice(&mut slice)?;
match ctx {
Endian::Big => Ok(Self::from_be_bytes(slice)),
Endian::Little => Ok(Self::from_le_bytes(slice)),
Endian::Host => Ok(Self::from_ne_bytes(slice)),
}
}
}
impl<A: Copy, T: Default + Copy + Codec<A>, const SIZE: usize> Codec<A> for [T; SIZE] {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: A) -> Result<(), EncodeError> {
for i in self {
i.encode(buf, ctx)?;
}
Ok(())
}
fn decode(buf: &mut impl DecodeBuffer, ctx: A) -> Result<Self, DecodeError> {
let mut result = [T::default(); SIZE];
for i in 0..SIZE {
result[i] = T::decode(buf, ctx)?;
}
Ok(result)
}
}
impl Codec<()> for bool {
fn encode(&self, buf: &mut impl EncodeBuffer, _: ()) -> Result<(), EncodeError> {
if *self {
1u8.encode(buf, ())
} else {
0u8.encode(buf, ())
}
}
fn decode(buf: &mut impl DecodeBuffer, _: ()) -> Result<Self, DecodeError> {
let value: u8 = u8::decode(buf, ())?;
match value {
0 => Ok(false),
1 => Ok(true),
_ => Err(DecodeError::Invalid),
}
}
}
pub enum SizeContext {
Fixed(usize),
U8Len,
U16Len(Endian),
U32Len(Endian),
NullTerminated,
}
impl<const SIZE: usize, Type: Codec<()>> Codec<SizeContext> for Vec<Type, SIZE> {
fn encode(&self, buf: & mut impl EncodeBuffer, ctx: SizeContext) -> Result<(), EncodeError> {
match ctx {
SizeContext::Fixed(len) => if len != self.len() {return Err(EncodeError::Encoding)},
SizeContext::U8Len => (self.len() as u8).encode(buf, ())?,
SizeContext::U16Len(endian) => (self.len() as u16).encode(buf, endian)?,
SizeContext::U32Len(endian) => (self.len() as u32).encode(buf, endian)?,
SizeContext::NullTerminated => unimplemented!("Not reasonable"),
};
for i in self {
i.encode(buf, ())?;
}
Ok(())
}
fn decode(buf: &mut impl DecodeBuffer, ctx: SizeContext) -> Result<Self, DecodeError> {
let size = match ctx {
SizeContext::Fixed(len) => len,
SizeContext::U8Len => u8::decode(buf, ())? as usize,
SizeContext::U16Len(endian) => u16::decode(buf, endian)? as usize,
SizeContext::U32Len(endian) => u32::decode(buf, endian)? as usize,
SizeContext::NullTerminated => unimplemented!("Not reasonable"),
};
let mut result = Vec::new();
for _ in 0..size {
result.push(Type::decode(buf, ())?).map_err(|_| {DecodeError::Invalid})?;
}
Ok(result)
}
}
impl<const SIZE: usize> Codec<SizeContext> for String<SIZE> {
fn encode(&self, buf: &mut impl EncodeBuffer, ctx: SizeContext) -> Result<(), EncodeError> {
match ctx {
SizeContext::Fixed(usize) => {
let slice = self.as_bytes();
let length = slice.len();
if length > usize {return Err(EncodeError::Encoding)}
buf.push_slice(self.as_bytes())?;
for _ in 0..usize-length {
buf.push(0)?;
}
Ok(())
},
SizeContext::U8Len => {
let slice = self.as_bytes();
let length = u8::try_from(slice.len()).or_else(|_| Err(EncodeError::Encoding))?;
buf.push(length)?;
buf.push_slice(self.as_bytes())
},
SizeContext::U16Len(end) => {
let slice = self.as_bytes();
let length = u16::try_from(slice.len()).or_else(|_| Err(EncodeError::Encoding))?;
length.encode(buf, end)?;
buf.push_slice(self.as_bytes())
},
SizeContext::U32Len(end) => {
let slice = self.as_bytes();
let length = u32::try_from(slice.len()).or_else(|_| Err(EncodeError::Encoding))?;
length.encode(buf, end)?;
buf.push_slice(self.as_bytes())
},
SizeContext::NullTerminated => {
buf.push_slice(self.as_bytes())?;
buf.push(0)
},
}
}
fn decode(buf: &mut impl DecodeBuffer, ctx: SizeContext) -> Result<Self, DecodeError> {
match ctx {
SizeContext::Fixed(size) => {
let mut temp_buf = [0u8;SIZE];
buf.read_slice(&mut temp_buf[0..size])?;
let vec: Vec<_, SIZE> = Vec::from_slice(&temp_buf[0..size]).or_else(|_| Err(DecodeError::Invalid))?;
String::<SIZE>::from_utf8(vec).or_else(|_| Err(DecodeError::Invalid))
}
SizeContext::U8Len => {
let mut temp_buf = [0u8;SIZE];
let len = u8::decode(buf, ())?;
let len = len as usize;
if len > SIZE {return Err(DecodeError::Invalid);}
buf.read_slice(&mut temp_buf[0..len])?;
let vec: Vec<_, SIZE> = Vec::from_slice(&temp_buf[0..len]).or_else(|_| Err(DecodeError::Invalid))?;
String::<SIZE>::from_utf8(vec).or_else(|_| Err(DecodeError::Invalid))
}
SizeContext::U16Len(end) => {
let mut temp_buf = [0u8;SIZE];
let len = u16::decode(buf, end)?;
let len = len as usize;
if len > SIZE {return Err(DecodeError::Invalid);}
buf.read_slice(&mut temp_buf[0..len])?;
let vec: Vec<_, SIZE> = Vec::from_slice(&temp_buf[0..len]).or_else(|_| Err(DecodeError::Invalid))?;
String::<SIZE>::from_utf8(vec).or_else(|_| Err(DecodeError::Invalid))
}
SizeContext::U32Len(end) => {
let mut temp_buf = [0u8;SIZE];
let len = u32::decode(buf, end)?;
let len = len as usize;
if len > SIZE {return Err(DecodeError::Invalid);}
buf.read_slice(&mut temp_buf[0..len])?;
let vec: Vec<_, SIZE> = Vec::from_slice(&temp_buf[0..len]).or_else(|_| Err(DecodeError::Invalid))?;
String::<SIZE>::from_utf8(vec).or_else(|_| Err(DecodeError::Invalid))
}
SizeContext::NullTerminated => {
let mut vec = Vec::<u8, SIZE>::new();
loop {
let char = u8::decode(buf, ())?;
if char == 0 {break}
vec.push(char).or_else(|_| Err(DecodeError::Invalid))?;
}
String::<SIZE>::from_utf8(vec).or_else(|_| Err(DecodeError::Invalid))
}
}
}
}