tsuzuri 0.1.285

Tsuzuri is a Event Sourcing framework for Rust, designed to be simple and easy to use.
Documentation
use prost::bytes::Bytes;
use serde::{Deserialize, Serialize};
use std::fmt::Display;
use std::marker::PhantomData;

#[derive(Debug, thiserror::Error)]
pub enum SerdeError {
    #[error("failed to convert type values: {0}")]
    ConversionError(String),
    #[error("JSON error: {0}")]
    JsonError(#[from] serde_json::Error),
    #[error("failed to deserialize protobuf message into value: {0}")]
    ProtobufDeserializationError(#[from] prost::DecodeError),
}

pub trait Serializer<T>: Send + Sync {
    fn serialize(&self, value: &T) -> Result<Vec<u8>, SerdeError>;
}

pub trait Deserializer<T>: Send + Sync {
    fn deserialize(&self, data: &[u8]) -> Result<T, SerdeError>;
}

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> + Clone + Send + Sync,
    Out: TryFrom<In> + Send + Sync,
    <Out as TryFrom<In>>::Error: Display,
    S: Serde<Out> + Send + Sync,
{
    fn serialize(&self, value: &In) -> Result<Vec<u8>, SerdeError> {
        let out: Out = value
            .clone()
            .try_into()
            .map_err(|err: <Out as TryFrom<In>>::Error| SerdeError::ConversionError(err.to_string()))?;

        self.serde.serialize(&out)
    }
}

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]) -> Result<In, SerdeError> {
        let out = self.serde.deserialize(data)?;

        out.try_into()
            .map_err(|err: <In as TryFrom<Out>>::Error| SerdeError::ConversionError(err.to_string()))
    }
}

#[derive(Debug, Clone, Copy)]
pub struct Json<T>(PhantomData<T>)
where
    T: Serialize + Send + Sync,
    for<'d> T: Deserialize<'d>;

impl<T> Default for Json<T>
where
    T: Serialize + Send + Sync,
    for<'d> T: Deserialize<'d>,
{
    fn default() -> Self {
        Self(PhantomData)
    }
}

impl<T> Serializer<T> for Json<T>
where
    T: Serialize + Send + Sync,
    for<'d> T: Deserialize<'d>,
{
    fn serialize(&self, value: &T) -> Result<Vec<u8>, SerdeError> {
        Ok(serde_json::to_vec(value)?)
    }
}

impl<T> Deserializer<T> for Json<T>
where
    T: Serialize + Send + Sync,
    for<'d> T: Deserialize<'d>,
{
    fn deserialize(&self, data: &[u8]) -> Result<T, SerdeError> {
        Ok(serde_json::from_slice(data)?)
    }
}

#[derive(Debug, Clone, Copy, Default)]
pub struct Protobuf<T>(PhantomData<T>)
where
    T: prost::Message + Default;

impl<T> Serializer<T> for Protobuf<T>
where
    T: prost::Message + Default,
{
    fn serialize(&self, value: &T) -> Result<Vec<u8>, SerdeError> {
        Ok(value.encode_to_vec())
    }
}

impl<T> Deserializer<T> for Protobuf<T>
where
    T: prost::Message + Default,
{
    fn deserialize(&self, data: &[u8]) -> Result<T, SerdeError> {
        let buf = Bytes::copy_from_slice(data);
        Ok(T::decode(buf)?)
    }
}

#[derive(Clone, Copy, Default)]
pub struct ProtoJson<T>(PhantomData<T>)
where
    T: prost::Message + Serialize + Default,
    for<'de> T: Deserialize<'de>;

impl<T> Serializer<T> for ProtoJson<T>
where
    T: prost::Message + Serialize + Default,
    for<'de> T: Deserialize<'de>,
{
    fn serialize(&self, value: &T) -> Result<Vec<u8>, SerdeError> {
        Json::<T>::default().serialize(value)
    }
}

impl<T> Deserializer<T> for ProtoJson<T>
where
    T: prost::Message + Serialize + Default,
    for<'de> T: Deserialize<'de>,
{
    fn deserialize(&self, data: &[u8]) -> Result<T, SerdeError> {
        Json::<T>::default().deserialize(data)
    }
}