use std::fmt::Display;
use std::marker::PhantomData;
use anyhow::anyhow;
#[cfg(feature = "serde-prost")]
use prost::bytes::Bytes;
#[cfg(feature = "serde-json")]
use serde::{Deserialize, Serialize};
pub trait Serializer<T>: Send + Sync {
fn serialize(&self, value: T) -> anyhow::Result<Vec<u8>>;
}
pub trait Deserializer<T>: Send + Sync {
fn deserialize(&self, data: &[u8]) -> anyhow::Result<T>;
}
pub trait Serde<T>: Serializer<T> + Deserializer<T> + Send + Sync {}
impl<S, T> Serde<T> for S where S: Serializer<T> + Deserializer<T> {}
#[derive(Clone, Copy)]
pub struct Convert<In, Out, S>
where
In: Send + Sync,
Out: Send + Sync,
S: Serde<Out> + Send + Sync,
{
serde: S,
inn: PhantomData<In>,
out: PhantomData<Out>,
}
impl<In, Out, S> Convert<In, Out, S>
where
In: Send + Sync,
Out: Send + Sync,
S: Serde<Out> + Send + Sync,
{
pub fn new(serde: S) -> Self {
Self {
serde,
inn: PhantomData,
out: PhantomData,
}
}
}
impl<In, Out, S> Serializer<In> for Convert<In, Out, S>
where
In: TryFrom<Out> + Send + Sync,
Out: TryFrom<In> + Send + Sync,
<Out as TryFrom<In>>::Error: Display,
S: Serde<Out> + Send + Sync,
{
fn serialize(&self, value: In) -> anyhow::Result<Vec<u8>> {
self.serde.serialize(
value
.try_into()
.map_err(|err| anyhow!("failed to convert type values: {}", err))?,
)
}
}
impl<In, Out, S> Deserializer<In> for Convert<In, Out, S>
where
In: TryFrom<Out> + Send + Sync,
Out: TryFrom<In> + Send + Sync,
<In as TryFrom<Out>>::Error: Display,
S: Serde<Out> + Send + Sync,
{
fn deserialize(&self, data: &[u8]) -> anyhow::Result<In> {
let inn = self.serde.deserialize(data)?;
inn.try_into()
.map_err(|err| anyhow!("failed to convert type values: {}", err))
}
}
#[cfg(feature = "serde-json")]
#[derive(Debug, Clone, Copy)]
pub struct Json<T>(PhantomData<T>)
where
T: Serialize + Send + Sync,
for<'d> T: Deserialize<'d>;
#[cfg(feature = "serde-json")]
impl<T> Default for Json<T>
where
T: Serialize + Send + Sync,
for<'d> T: Deserialize<'d>,
{
fn default() -> Self {
Self(PhantomData)
}
}
#[cfg(feature = "serde-json")]
impl<T> Serializer<T> for Json<T>
where
T: Serialize + Send + Sync,
for<'d> T: Deserialize<'d>,
{
fn serialize(&self, value: T) -> anyhow::Result<Vec<u8>> {
serde_json::to_vec(&value)
.map_err(|err| anyhow!("failed to serialize value to json: {}", err))
}
}
#[cfg(feature = "serde-json")]
impl<T> Deserializer<T> for Json<T>
where
T: Serialize + Send + Sync,
for<'d> T: Deserialize<'d>,
{
fn deserialize(&self, data: &[u8]) -> anyhow::Result<T> {
serde_json::from_slice(data)
.map_err(|err| anyhow!("failed to deserialize value from json: {}", err))
}
}
#[cfg(feature = "serde-prost")]
#[derive(Debug, Clone, Copy, Default)]
pub struct Protobuf<T>(PhantomData<T>)
where
T: prost::Message + Default;
#[cfg(feature = "serde-prost")]
impl<T> Serializer<T> for Protobuf<T>
where
T: prost::Message + Default,
{
fn serialize(&self, value: T) -> anyhow::Result<Vec<u8>> {
Ok(value.encode_to_vec())
}
}
#[cfg(feature = "serde-prost")]
impl<T> Deserializer<T> for Protobuf<T>
where
T: prost::Message + Default,
{
fn deserialize(&self, data: &[u8]) -> anyhow::Result<T> {
let buf = Bytes::copy_from_slice(data);
T::decode(buf)
.map_err(|err| anyhow!("failed to deserialize protobuf message into value: {}", err))
}
}
#[cfg(feature = "serde-prost")]
#[cfg(feature = "serde-json")]
#[derive(Clone, Copy, Default)]
pub struct ProtoJson<T>(PhantomData<T>)
where
T: prost::Message + Serialize + Default,
for<'de> T: Deserialize<'de>;
#[cfg(feature = "serde-prost")]
#[cfg(feature = "serde-json")]
impl<T> Serializer<T> for ProtoJson<T>
where
T: prost::Message + Serialize + Default,
for<'de> T: Deserialize<'de>,
{
fn serialize(&self, value: T) -> anyhow::Result<Vec<u8>> {
Json::<T>::default().serialize(value)
}
}
#[cfg(feature = "serde-prost")]
#[cfg(feature = "serde-json")]
impl<T> Deserializer<T> for ProtoJson<T>
where
T: prost::Message + Serialize + Default,
for<'de> T: Deserialize<'de>,
{
fn deserialize(&self, data: &[u8]) -> anyhow::Result<T> {
Json::<T>::default().deserialize(data)
}
}