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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#[cfg(all(feature = "deser_borsh", feature = "deser_json"))]
pub trait Serialize: borsh::BorshSerialize + serde::Serialize {}
#[cfg(all(feature = "deser_borsh", feature = "deser_json"))]
impl<T> Serialize for T where T: borsh::BorshSerialize + serde::Serialize {}
#[cfg(all(feature = "deser_borsh", feature = "deser_json"))]
pub trait Deserialize: borsh::BorshDeserialize + serde::de::DeserializeOwned {}
#[cfg(all(feature = "deser_borsh", feature = "deser_json"))]
impl<T> Deserialize for T where T: borsh::BorshDeserialize + serde::de::DeserializeOwned {}
#[cfg(all(feature = "deser_borsh", not(feature = "deser_json")))]
pub trait Serialize: borsh::BorshSerialize {}
#[cfg(all(feature = "deser_borsh", not(feature = "deser_json")))]
impl<T> Serialize for T where T: borsh::BorshSerialize {}
#[cfg(all(feature = "deser_borsh", not(feature = "deser_json")))]
pub trait Deserialize: borsh::BorshDeserialize {}
#[cfg(all(feature = "deser_borsh", not(feature = "deser_json")))]
impl<T> Deserialize for T where T: borsh::BorshDeserialize {}
#[derive(Debug, Copy, Clone)]
pub enum Deser {
#[cfg(feature = "deser_borsh")]
Borsh,
#[cfg(feature = "deser_json")]
Json,
}
impl Deser {
pub fn from_slice<T>(&self, bytes: &[u8]) -> Result<T, Error>
where
T: Deserialize,
{
match self {
#[cfg(feature = "deser_borsh")]
Self::Borsh => {
Ok(<T as borsh::BorshDeserialize>::try_from_slice(bytes)
.map_err(Error::Borsh)?)
}
#[cfg(feature = "deser_json")]
Self::Json => Ok(serde_json::from_slice(bytes)?),
}
}
pub fn to_vec<T>(&self, t: &T) -> Result<Vec<u8>, Error>
where
T: Serialize,
{
match self {
#[cfg(feature = "deser_borsh")]
Self::Borsh => {
Ok(<T as borsh::BorshSerialize>::try_to_vec(t)
.map_err(Error::Borsh)?)
}
#[cfg(feature = "deser_json")]
Self::Json => Ok(cjson::to_vec(t)?),
}
}
}
#[cfg(all(feature = "deser_borsh"))]
impl Default for Deser {
fn default() -> Self {
Self::Borsh
}
}
#[cfg(all(feature = "deser_json", not(feature = "deser_borsh")))]
impl Default for Deser {
fn default() -> Self {
Self::Json
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[cfg(feature = "deser_borsh")]
#[error("borsh error: `{0:?}`")]
Borsh(std::io::Error),
#[cfg(feature = "deser_json")]
#[error("serde_json error: `{0:?}`")]
SerdeJson(#[from] serde_json::Error),
#[cfg(feature = "deser_json")]
#[error("cjson error: `{0:?}`")]
Cjson(cjson::Error),
}
#[cfg(feature = "deser_json")]
impl From<cjson::Error> for Error {
fn from(err: cjson::Error) -> Self {
Self::Cjson(err)
}
}
#[cfg(test)]
pub mod test {
use {super::*, crate::value::Value};
#[cfg(feature = "deser_borsh")]
#[tokio::test]
async fn borsh() {
let mut env_builder = env_logger::builder();
env_builder.is_test(true);
if std::env::var("RUST_LOG").is_err() {
env_builder.filter(Some("fixity"), log::LevelFilter::Debug);
}
let expected = Value::from(1);
let bytes = Deser::to_vec(&Deser::Borsh, &expected).unwrap();
let got = Deser::from_slice::<Value>(&Deser::Borsh, &bytes).unwrap();
assert_eq!(expected, got);
}
#[cfg(feature = "deser_json")]
#[tokio::test]
async fn json() {
let mut env_builder = env_logger::builder();
env_builder.is_test(true);
if std::env::var("RUST_LOG").is_err() {
env_builder.filter(Some("fixity"), log::LevelFilter::Debug);
}
let expected = Value::from(1);
let bytes = Deser::to_vec(&Deser::Json, &expected).unwrap();
let got = Deser::from_slice::<Value>(&Deser::Json, &bytes).unwrap();
assert_eq!(expected, got);
}
}