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 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 is_set: u8 = u8::decode(buf, ())?;
Ok(is_set != 0)
}
}
pub enum SizeContext {
Fixed(usize),
U8Len,
U16Len(Endian),
U32Len(Endian),
NullTerminated,
}
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))
}
}
}
}