near_primitives_core_v01/
serialize.rs

1use std::convert::TryFrom;
2
3pub fn to_base<T: AsRef<[u8]>>(input: T) -> String {
4    bs58::encode(input).into_string()
5}
6
7pub fn from_base(s: &str) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
8    bs58::decode(s).into_vec().map_err(|err| err.into())
9}
10
11pub fn to_base64<T: AsRef<[u8]>>(input: T) -> String {
12    base64::encode(&input)
13}
14
15pub fn from_base64(s: &str) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
16    base64::decode(s).map_err(|err| err.into())
17}
18
19pub fn from_base_buf(s: &str, buffer: &mut Vec<u8>) -> Result<(), Box<dyn std::error::Error>> {
20    match bs58::decode(s).into(buffer) {
21        Ok(_) => Ok(()),
22        Err(err) => Err(err.into()),
23    }
24}
25
26pub trait BaseEncode {
27    fn to_base(&self) -> String;
28}
29
30impl<T> BaseEncode for T
31where
32    for<'a> &'a T: Into<Vec<u8>>,
33{
34    fn to_base(&self) -> String {
35        to_base(&self.into())
36    }
37}
38
39pub trait BaseDecode: for<'a> TryFrom<&'a [u8], Error = Box<dyn std::error::Error>> {
40    fn from_base(s: &str) -> Result<Self, Box<dyn std::error::Error>> {
41        let bytes = from_base(s)?;
42        Self::try_from(&bytes)
43    }
44}
45
46pub mod base64_format {
47    use serde::de;
48    use serde::{Deserialize, Deserializer, Serializer};
49
50    use super::{from_base64, to_base64};
51
52    pub fn serialize<S, T>(data: T, serializer: S) -> Result<S::Ok, S::Error>
53    where
54        S: Serializer,
55        T: AsRef<[u8]>,
56    {
57        serializer.serialize_str(&to_base64(data))
58    }
59
60    pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
61    where
62        D: Deserializer<'de>,
63        T: From<Vec<u8>>,
64    {
65        let s = String::deserialize(deserializer)?;
66        from_base64(&s).map_err(|err| de::Error::custom(err.to_string())).map(Into::into)
67    }
68}
69
70pub mod option_base64_format {
71    use serde::de;
72    use serde::{Deserialize, Deserializer, Serializer};
73
74    use super::{from_base64, to_base64};
75
76    pub fn serialize<S>(data: &Option<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>
77    where
78        S: Serializer,
79    {
80        if let Some(ref bytes) = data {
81            serializer.serialize_str(&to_base64(bytes))
82        } else {
83            serializer.serialize_none()
84        }
85    }
86
87    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
88    where
89        D: Deserializer<'de>,
90    {
91        let s: Option<String> = Option::deserialize(deserializer)?;
92        if let Some(s) = s {
93            Ok(Some(from_base64(&s).map_err(|err| de::Error::custom(err.to_string()))?))
94        } else {
95            Ok(None)
96        }
97    }
98}
99
100pub mod base_bytes_format {
101    use serde::de;
102    use serde::{Deserialize, Deserializer, Serializer};
103
104    use super::{from_base, to_base};
105
106    pub fn serialize<S>(data: &[u8], serializer: S) -> Result<S::Ok, S::Error>
107    where
108        S: Serializer,
109    {
110        serializer.serialize_str(&to_base(data))
111    }
112
113    pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
114    where
115        D: Deserializer<'de>,
116    {
117        let s = String::deserialize(deserializer)?;
118        from_base(&s).map_err(|err| de::Error::custom(err.to_string()))
119    }
120}
121
122pub mod u64_dec_format {
123    use serde::de;
124    use serde::{Deserialize, Deserializer, Serializer};
125
126    pub fn serialize<S>(num: &u64, serializer: S) -> Result<S::Ok, S::Error>
127    where
128        S: Serializer,
129    {
130        serializer.serialize_str(&format!("{}", num))
131    }
132
133    pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
134    where
135        D: Deserializer<'de>,
136    {
137        let s = String::deserialize(deserializer)?;
138        u64::from_str_radix(&s, 10).map_err(de::Error::custom)
139    }
140}
141
142pub mod u128_dec_format {
143    use serde::de;
144    use serde::{Deserialize, Deserializer, Serializer};
145
146    pub fn serialize<S>(num: &u128, serializer: S) -> Result<S::Ok, S::Error>
147    where
148        S: Serializer,
149    {
150        serializer.serialize_str(&format!("{}", num))
151    }
152
153    pub fn deserialize<'de, D>(deserializer: D) -> Result<u128, D::Error>
154    where
155        D: Deserializer<'de>,
156    {
157        let s = String::deserialize(deserializer)?;
158        u128::from_str_radix(&s, 10).map_err(de::Error::custom)
159    }
160}
161
162pub mod u128_dec_format_compatible {
163    //! This in an extension to `u128_dec_format` that serves a compatibility layer role to
164    //! deserialize u128 from a "small" JSON number (u64).
165    //!
166    //! It is unfortunate that we cannot enable "arbitrary_precision" feature in
167    //! serde_json due to a bug: <https://github.com/serde-rs/json/issues/505>.
168    use serde::{de, Deserialize, Deserializer};
169
170    pub use super::u128_dec_format::serialize;
171
172    #[derive(Deserialize)]
173    #[serde(untagged)]
174    enum U128 {
175        Number(u64),
176        String(String),
177    }
178
179    pub fn deserialize<'de, D>(deserializer: D) -> Result<u128, D::Error>
180    where
181        D: Deserializer<'de>,
182    {
183        match U128::deserialize(deserializer)? {
184            U128::Number(value) => Ok(u128::from(value)),
185            U128::String(value) => u128::from_str_radix(&value, 10).map_err(de::Error::custom),
186        }
187    }
188}
189
190pub mod option_u128_dec_format {
191    use serde::de;
192    use serde::{Deserialize, Deserializer, Serializer};
193
194    pub fn serialize<S>(data: &Option<u128>, serializer: S) -> Result<S::Ok, S::Error>
195    where
196        S: Serializer,
197    {
198        if let Some(ref num) = data {
199            serializer.serialize_str(&format!("{}", num))
200        } else {
201            serializer.serialize_none()
202        }
203    }
204
205    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<u128>, D::Error>
206    where
207        D: Deserializer<'de>,
208    {
209        let s: Option<String> = Option::deserialize(deserializer)?;
210        if let Some(s) = s {
211            Ok(Some(u128::from_str_radix(&s, 10).map_err(de::Error::custom)?))
212        } else {
213            Ok(None)
214        }
215    }
216}