use anyhow::Result;
use bytes::{BufMut, Bytes, BytesMut};
use serde::{Deserialize, Serialize};
use tracing::instrument;
use crate::config::{self, Config};
pub trait Serializable: Serialize + for<'de> Deserialize<'de> + Send + Sync + Unpin {}
impl<T> Serializable for T where T: Serialize + for<'de> Deserialize<'de> + Send + Sync + Unpin {}
#[derive(Clone, Copy, Serialize, Deserialize, Debug, Default)]
pub enum Serializer {
#[default]
Postcard,
Cbor,
}
impl std::fmt::Display for Serializer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Postcard => write!(f, "postcard"),
Self::Cbor => write!(f, "cbor"),
}
}
}
impl Serializer {
#[instrument(skip(value), level = "trace")]
pub fn to_bytes<T: Serialize>(&self, value: &T) -> Result<Bytes> {
let mut buf = BytesMut::new().writer();
let buf = match self {
Self::Postcard => postcard::to_io(value, buf)?,
Self::Cbor => {
ciborium::into_writer(value, &mut buf)?;
buf
}
};
Ok(buf.into_inner().freeze())
}
#[instrument(skip(bytes), level = "trace")]
pub fn from_bytes<T: for<'a> Deserialize<'a>>(&self, bytes: &[u8]) -> Result<T> {
match self {
Self::Postcard => Ok(postcard::from_bytes(bytes)?),
Self::Cbor => Ok(ciborium::from_reader(bytes)?),
}
}
}
impl From<&Config> for Serializer {
fn from(config: &Config) -> Self {
match config.serializer {
config::Serializer::Postcard => Self::Postcard,
config::Serializer::Cbor => Self::Cbor,
}
}
}