use std::fmt::Debug;
use serde::{Serialize, de::DeserializeOwned};
use tracing::{error, trace};
use crate::error::Error;
pub struct Json;
pub struct PostcardCobs;
pub struct Null;
pub struct Bytes;
pub trait Codec<OUT: Send + 'static, IN: Send + 'static>: Send + Sized + 'static {
fn encode(item: &OUT) -> Result<Vec<u8>, Error>;
fn try_decode(buff: &mut Vec<u8>) -> Result<Option<IN>, Error>;
}
impl<OUT: Serialize + Debug + Send + 'static, IN: DeserializeOwned + Debug + Send + 'static>
Codec<OUT, IN> for Json
{
fn encode(item: &OUT) -> Result<Vec<u8>, Error> {
let b = serde_json::to_vec(item).map_err(|e| Error::Json(e))?;
trace!("Encoded {item:?} to bytes: {:?}", b);
Ok(b)
}
fn try_decode(buff: &mut Vec<u8>) -> Result<Option<IN>, Error> {
let mut deserializer = serde_json::Deserializer::from_slice(&buff).into_iter::<IN>();
let res = match deserializer.next() {
Some(Ok(cmd)) => {
Ok(Some(cmd))
}
Some(Err(e)) if e.is_eof() => {
Ok(None)
}
Some(Err(e)) => {
error!("Failed to deserialize message: {:?}", e);
if buff.len() > 64 {
trace!("Buffer (truncated to 64 bytes): {:?}", &buff[..64]);
} else {
trace!("Buffer: {:?}", buff);
}
Err(Error::Json(e))
}
None => Ok(None), };
let consumed = deserializer.byte_offset();
buff.drain(..consumed);
res
}
}
impl<OUT: Serialize + Debug + Send + 'static, IN: DeserializeOwned + Debug + Send + 'static>
Codec<OUT, IN> for PostcardCobs
{
fn encode(item: &OUT) -> Result<Vec<u8>, Error> {
let b = postcard::to_allocvec_cobs(item).map_err(|e| Error::Postcard(e))?;
trace!("Encoded {item:?} to {} bytes", b.len());
Ok(b)
}
fn try_decode(buff: &mut Vec<u8>) -> Result<Option<IN>, Error> {
let pos = match buff.iter().position(|&b| b == 0) {
Some(pos) => pos,
None => return Ok(None), };
let mut frame = buff.drain(..=pos).collect::<Vec<u8>>();
match postcard::from_bytes_cobs::<IN>(&mut frame) {
Ok(cmd) => Ok(Some(cmd)),
Err(e) => {
error!("Failed to deserialize message: {:?}", e);
if frame.len() > 64 {
trace!("Buffer (truncated to 64 bytes): {:?}", &frame[..64]);
} else {
trace!("Buffer: {:?}", frame);
}
Err(Error::Postcard(e))
}
}
}
}
impl<OUT: Send + 'static, IN: Send + 'static> Codec<OUT, IN> for Null {
fn encode(_item: &OUT) -> Result<Vec<u8>, Error> {
Ok(Vec::new())
}
fn try_decode(_buff: &mut Vec<u8>) -> Result<Option<IN>, Error> {
Ok(None)
}
}
impl Codec<Vec<u8>, Vec<u8>> for Bytes {
fn encode(item: &Vec<u8>) -> Result<Vec<u8>, Error> {
Ok(item.clone())
}
fn try_decode(buff: &mut Vec<u8>) -> Result<Option<Vec<u8>>, Error> {
if buff.is_empty() {
Ok(None)
} else {
Ok(Some(buff.split_off(0)))
}
}
}