1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use crate::{Decoder, Encoder};
use serde_lite::{Deserialize, Intermediate, Serialize};

/// A wrapper codec that relies on [`serde_lite`]. With this, you can wrap serde based codecs that
/// also work with serde-lite like the [`JsonSerdeCodec`] or the [`MsgpackSerdeCodec`].
///
/// Only available with the **`serde_lite` feature** enabled plus the feature you need for the
/// wrapped codec.
///
/// ## Example
///
/// ```
/// use codee::{Encoder, Decoder, SerdeLite, string::JsonSerdeCodec, binary::MsgpackSerdeCodec};
/// use serde_lite::{Deserialize, Serialize};
///
/// #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
/// struct Test {
///     s: String,
///     i: i32,
/// }
///
/// let t = Test {
///     s: String::from("party time 🎉"),
///     i: 42,
/// };
///
/// let enc = SerdeLite::<JsonSerdeCodec>::encode(&t).unwrap();
/// let dec: Test = SerdeLite::<JsonSerdeCodec>::decode(&enc).unwrap();
///
/// let enc = SerdeLite::<MsgpackSerdeCodec>::encode(&t).unwrap();
/// let dec: Test = SerdeLite::<MsgpackSerdeCodec>::decode(&enc).unwrap();
/// assert_eq!(dec, t);
/// ```
pub struct SerdeLite<C>(C);

#[derive(Debug, thiserror::Error)]
pub enum SerdeLiteEncodeError<E> {
    #[error("Error from serde-lite: {0}")]
    SerdeLite(serde_lite::Error),
    #[error("Error from wrapped encoder")]
    Encoder(#[from] E),
}

#[derive(Debug, thiserror::Error)]
pub enum SerdeLiteDecodeError<E> {
    #[error("Error from serde-lite: {0}")]
    SerdeLite(serde_lite::Error),
    #[error("Error from wrapped decoder")]
    Decoder(#[from] E),
}

impl<T, E> Encoder<T> for SerdeLite<E>
where
    T: Serialize,
    E: Encoder<Intermediate>,
{
    type Error = SerdeLiteEncodeError<<E as Encoder<Intermediate>>::Error>;
    type Encoded = <E as Encoder<Intermediate>>::Encoded;

    fn encode(val: &T) -> Result<Self::Encoded, Self::Error> {
        let intermediate = val.serialize().map_err(SerdeLiteEncodeError::SerdeLite)?;
        Ok(E::encode(&intermediate)?)
    }
}

impl<T, D> Decoder<T> for SerdeLite<D>
where
    T: Deserialize,
    D: Decoder<Intermediate>,
{
    type Error = SerdeLiteDecodeError<<D as Decoder<Intermediate>>::Error>;
    type Encoded = <D as Decoder<Intermediate>>::Encoded;

    fn decode(val: &Self::Encoded) -> Result<T, Self::Error> {
        let intermediate = D::decode(val)?;
        T::deserialize(&intermediate).map_err(SerdeLiteDecodeError::SerdeLite)
    }
}