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
79
80
81
use cfg_if::cfg_if;
use std::rc::Rc;
use thiserror::Error;

#[derive(Debug, Clone, Error)]
pub enum SerializationError {
    #[error("error serializing Resource: {0}")]
    Serialize(Rc<dyn std::error::Error>),
    #[error("error deserializing Resource: {0}")]
    Deserialize(Rc<dyn std::error::Error>),
}

pub trait Serializable
where
    Self: Sized,
{
    fn to_json(&self) -> Result<String, SerializationError>;

    fn from_json(json: &str) -> Result<Self, SerializationError>;
}

cfg_if! {
    // prefer miniserde if it's chosen
    if #[cfg(feature = "miniserde")] {
        use miniserde::{json, Deserialize, Serialize};

        impl<T> Serializable for T
        where
            T: Serialize + Deserialize,
        {
            fn to_json(&self) -> Result<String, SerializationError> {
                Ok(json::to_string(&self))
            }

            fn from_json(json: &str) -> Result<Self, SerializationError> {
                json::from_str(&json).map_err(|e| SerializationError::Deserialize(Rc::new(e)))
            }
        }

    }
    // use serde-lite if enabled
    else if #[cfg(feature = "serde-lite")] {
        use serde_lite::{Deserialize, Serialize};

        impl<T> Serializable for T
        where
            T: Serialize + Deserialize,
        {
            fn to_json(&self) -> Result<String, SerializationError> {
                let intermediate = self
                    .serialize()
                    .map_err(|e| SerializationError::Serialize(Rc::new(e)))?;
                serde_json::to_string(&intermediate).map_err(|e| SerializationError::Serialize(Rc::new(e)))
            }

            fn from_json(json: &str) -> Result<Self, SerializationError> {
                let intermediate =
                    serde_json::from_str(&json).map_err(|e| SerializationError::Deserialize(Rc::new(e)))?;
                Self::deserialize(&intermediate).map_err(|e| SerializationError::Deserialize(Rc::new(e)))
            }
        }

    }
    // otherwise, or if serde is chosen, default to serde
    else {
        use serde::{de::DeserializeOwned, Serialize};

        impl<T> Serializable for T
        where
            T: DeserializeOwned + Serialize,
        {
            fn to_json(&self) -> Result<String, SerializationError> {
                serde_json::to_string(&self).map_err(|e| SerializationError::Serialize(Rc::new(e)))
            }

            fn from_json(json: &str) -> Result<Self, SerializationError> {
                serde_json::from_str(json).map_err(|e| SerializationError::Deserialize(Rc::new(e)))
            }
        }
    }
}