use crate::codec::Codec;
use serde::{Serialize, de::DeserializeOwned};
use std::{
error::Error,
io::{Read, Write},
marker::PhantomData,
};
pub struct PostcardCodec<T>(PhantomData<T>);
impl<T: Serialize + DeserializeOwned> Codec for PostcardCodec<T> {
type Value = T;
fn encode(message: &T, buffer: &mut dyn Write) -> Result<(), Box<dyn Error>> {
let data = postcard::to_allocvec(message)?;
buffer.write_all(&(data.len() as u64).to_le_bytes())?;
buffer.write_all(&data)?;
Ok(())
}
fn decode(buffer: &mut dyn Read) -> Result<T, Box<dyn Error>> {
let mut len_buf = [0u8; std::mem::size_of::<u64>()];
buffer.read_exact(&mut len_buf)?;
let len = u64::from_le_bytes(len_buf) as usize;
let mut data = vec![0u8; len];
buffer.read_exact(&mut data)?;
Ok(postcard::from_bytes::<T>(&data)?)
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde::{Deserialize, Serialize};
#[test]
fn test_postcard_codec() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct TestMessage {
id: u32,
}
let message = TestMessage { id: 42 };
let mut buffer = Vec::new();
PostcardCodec::<TestMessage>::encode(&message, &mut buffer).unwrap();
let decoded_message = PostcardCodec::<TestMessage>::decode(&mut buffer.as_slice()).unwrap();
assert_eq!(message, decoded_message);
}
}