use bincode::config::Configuration;
use bincode::serde::{borrow_decode_from_slice, encode_to_vec};
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[derive(Debug, Error)]
#[error(transparent)]
pub struct MarshalError(#[from] MarshalErrorRepr);
#[derive(Debug, Error)]
enum MarshalErrorRepr {
#[error("couldn't serialize with bincode: {0}")]
Serialize(#[from] bincode::error::EncodeError),
#[error("couldn't deserialize with bincode: {0}")]
Deserialize(#[from] bincode::error::DecodeError),
}
type MarshalResult<T> = Result<T, MarshalError>;
pub trait Marshal<'de>: Serialize + Deserialize<'de> {
const BINCODE_CONFIG: Configuration = bincode::config::legacy().with_variable_int_encoding();
fn to_byte_vec(&self) -> MarshalResult<Vec<u8>> {
Ok(encode_to_vec(self, Self::BINCODE_CONFIG).map_err(MarshalErrorRepr::Serialize)?)
}
fn from_bytes(bytes: &'de [u8]) -> MarshalResult<Self> {
let (decoded, _bytes_read) = borrow_decode_from_slice(bytes, Self::BINCODE_CONFIG)
.map_err(MarshalErrorRepr::Deserialize)?;
Ok(decoded)
}
}
impl<'de, T> Marshal<'de> for T where T: Serialize + Deserialize<'de> {}