eventually/
serde.rs

1//! This module provides traits and implementations for serialization and
2//! deserialization, allowing you to convert Rust data structures to and from
3//! different formats like JSON, Protobuf, etc.
4
5use std::fmt::Display;
6use std::marker::PhantomData;
7
8use anyhow::anyhow;
9#[cfg(feature = "serde-prost")]
10use prost::bytes::Bytes;
11#[cfg(feature = "serde-json")]
12use serde::{Deserialize, Serialize};
13
14/// A serializer interface that can be used to serialize a Rust data type
15/// into a specific wire format as a byte array.
16pub trait Serializer<T>: Send + Sync {
17    /// Serializes the given value into the protocol supported by this implementation.
18    ///
19    /// # Errors
20    ///
21    /// An error ([`anyhow::Error`]) is returned in case the serialization could not
22    /// succeed as expected.
23    fn serialize(&self, value: T) -> anyhow::Result<Vec<u8>>;
24}
25
26/// A deserializer interface that can be used to deserialize a byte array
27/// into an instance of a specific Rust data type from a specific wire format.
28pub trait Deserializer<T>: Send + Sync {
29    /// Deserializes the given value from a message encoded in the wire format
30    /// supported by this implementation.
31    ///
32    /// # Errors
33    ///
34    /// An error ([`anyhow::Error`]) is returned in case the deserialization could not
35    /// succeed as expected.
36    fn deserialize(&self, data: &[u8]) -> anyhow::Result<T>;
37}
38
39/// [Serializer] and [Deserializer] that can be used to serialize into and deserialize
40/// from a given type into a specific wire format, such as JSON, Protobuf, etc.
41pub trait Serde<T>: Serializer<T> + Deserializer<T> + Send + Sync {}
42
43impl<S, T> Serde<T> for S where S: Serializer<T> + Deserializer<T> {}
44
45/// Implements the [Serde] trait to translate between two different types,
46/// and using the specified [Serde] for serialization and deserialization
47/// using the new `Out` type.
48#[derive(Clone, Copy)]
49pub struct Convert<In, Out, S>
50where
51    In: Send + Sync,
52    Out: Send + Sync,
53    S: Serde<Out> + Send + Sync,
54{
55    serde: S,
56    inn: PhantomData<In>,
57    out: PhantomData<Out>,
58}
59
60impl<In, Out, S> Convert<In, Out, S>
61where
62    In: Send + Sync,
63    Out: Send + Sync,
64    S: Serde<Out> + Send + Sync,
65{
66    /// Creates a new [Convert] serde instance.
67    pub fn new(serde: S) -> Self {
68        Self {
69            serde,
70            inn: PhantomData,
71            out: PhantomData,
72        }
73    }
74}
75
76impl<In, Out, S> Serializer<In> for Convert<In, Out, S>
77where
78    In: TryFrom<Out> + Send + Sync,
79    Out: TryFrom<In> + Send + Sync,
80    <Out as TryFrom<In>>::Error: Display,
81    S: Serde<Out> + Send + Sync,
82{
83    fn serialize(&self, value: In) -> anyhow::Result<Vec<u8>> {
84        self.serde.serialize(
85            value
86                .try_into()
87                .map_err(|err| anyhow!("failed to convert type values: {}", err))?,
88        )
89    }
90}
91
92impl<In, Out, S> Deserializer<In> for Convert<In, Out, S>
93where
94    In: TryFrom<Out> + Send + Sync,
95    Out: TryFrom<In> + Send + Sync,
96    <In as TryFrom<Out>>::Error: Display,
97    S: Serde<Out> + Send + Sync,
98{
99    fn deserialize(&self, data: &[u8]) -> anyhow::Result<In> {
100        let inn = self.serde.deserialize(data)?;
101
102        inn.try_into()
103            .map_err(|err| anyhow!("failed to convert type values: {}", err))
104    }
105}
106
107/// Implements the [Serializer] and [Deserializer] traits, which use the [serde] crate
108/// to serialize and deserialize a message into JSON.
109#[cfg(feature = "serde-json")]
110#[derive(Debug, Clone, Copy)]
111pub struct Json<T>(PhantomData<T>)
112where
113    T: Serialize + Send + Sync,
114    for<'d> T: Deserialize<'d>;
115
116#[cfg(feature = "serde-json")]
117impl<T> Default for Json<T>
118where
119    T: Serialize + Send + Sync,
120    for<'d> T: Deserialize<'d>,
121{
122    fn default() -> Self {
123        Self(PhantomData)
124    }
125}
126
127#[cfg(feature = "serde-json")]
128impl<T> Serializer<T> for Json<T>
129where
130    T: Serialize + Send + Sync,
131    for<'d> T: Deserialize<'d>,
132{
133    fn serialize(&self, value: T) -> anyhow::Result<Vec<u8>> {
134        serde_json::to_vec(&value)
135            .map_err(|err| anyhow!("failed to serialize value to json: {}", err))
136    }
137}
138
139#[cfg(feature = "serde-json")]
140impl<T> Deserializer<T> for Json<T>
141where
142    T: Serialize + Send + Sync,
143    for<'d> T: Deserialize<'d>,
144{
145    fn deserialize(&self, data: &[u8]) -> anyhow::Result<T> {
146        serde_json::from_slice(data)
147            .map_err(|err| anyhow!("failed to deserialize value from json: {}", err))
148    }
149}
150
151/// Implements the [Serde] trait  which serializes and deserializes
152/// the message using Protobuf format through the [`prost::Message`] trait.
153#[cfg(feature = "serde-prost")]
154#[derive(Debug, Clone, Copy, Default)]
155pub struct Protobuf<T>(PhantomData<T>)
156where
157    T: prost::Message + Default;
158
159#[cfg(feature = "serde-prost")]
160impl<T> Serializer<T> for Protobuf<T>
161where
162    T: prost::Message + Default,
163{
164    fn serialize(&self, value: T) -> anyhow::Result<Vec<u8>> {
165        Ok(value.encode_to_vec())
166    }
167}
168
169#[cfg(feature = "serde-prost")]
170impl<T> Deserializer<T> for Protobuf<T>
171where
172    T: prost::Message + Default,
173{
174    fn deserialize(&self, data: &[u8]) -> anyhow::Result<T> {
175        let buf = Bytes::copy_from_slice(data);
176
177        T::decode(buf)
178            .map_err(|err| anyhow!("failed to deserialize protobuf message into value: {}", err))
179    }
180}
181
182/// Implementation of [Serde] traits that uses [ProtoJson](https://protobuf.dev/programming-guides/proto3/#json)
183/// as wire protocol.
184#[cfg(feature = "serde-prost")]
185#[cfg(feature = "serde-json")]
186#[derive(Clone, Copy, Default)]
187pub struct ProtoJson<T>(PhantomData<T>)
188where
189    T: prost::Message + Serialize + Default,
190    for<'de> T: Deserialize<'de>;
191
192#[cfg(feature = "serde-prost")]
193#[cfg(feature = "serde-json")]
194impl<T> Serializer<T> for ProtoJson<T>
195where
196    T: prost::Message + Serialize + Default,
197    for<'de> T: Deserialize<'de>,
198{
199    fn serialize(&self, value: T) -> anyhow::Result<Vec<u8>> {
200        Json::<T>::default().serialize(value)
201    }
202}
203
204#[cfg(feature = "serde-prost")]
205#[cfg(feature = "serde-json")]
206impl<T> Deserializer<T> for ProtoJson<T>
207where
208    T: prost::Message + Serialize + Default,
209    for<'de> T: Deserialize<'de>,
210{
211    fn deserialize(&self, data: &[u8]) -> anyhow::Result<T> {
212        Json::<T>::default().deserialize(data)
213    }
214}