1use hex::FromHexError;
2
3fn decode_hex_with_prefix(val: &str) -> Result<Vec<u8>, FromHexError> {
4 let mut stripped: String =
5 if let Some(stripped) = val.strip_prefix("0x") { stripped } else { val }.into();
6
7 if !stripped.len().is_multiple_of(2) {
9 stripped.insert(0, '0');
11 }
12
13 hex::decode(&stripped)
14}
15
16pub mod hex_bytes {
18 use serde::{Deserialize, Deserializer, Serializer};
19
20 use super::decode_hex_with_prefix;
21
22 pub fn serialize<S, T>(x: T, s: S) -> Result<S::Ok, S::Error>
24 where
25 S: Serializer,
26 T: AsRef<[u8]>,
27 {
28 s.serialize_str(&format!("0x{}", hex::encode(x.as_ref())))
29 }
30
31 pub fn deserialize<'de, T, D>(d: D) -> Result<T, D::Error>
34 where
35 D: Deserializer<'de>,
36 T: From<Vec<u8>>,
37 {
38 let value = String::deserialize(d)?;
39 decode_hex_with_prefix(&value)
40 .map(Into::into)
41 .map_err(|e| serde::de::Error::custom(e.to_string()))
42 }
43}
44
45pub mod hex_bytes_option {
47 use serde::{Deserialize, Deserializer, Serializer};
48
49 use super::decode_hex_with_prefix;
50
51 pub fn serialize<S, T>(x: &Option<T>, s: S) -> Result<S::Ok, S::Error>
53 where
54 S: Serializer,
55 T: AsRef<[u8]>,
56 {
57 if let Some(x) = x {
58 s.serialize_str(&format!("0x{}", hex::encode(x.as_ref())))
59 } else {
60 s.serialize_none()
61 }
62 }
63
64 pub fn deserialize<'de, T, D>(d: D) -> Result<Option<T>, D::Error>
67 where
68 D: Deserializer<'de>,
69 T: From<Vec<u8>>,
70 {
71 let value: Option<String> = Option::deserialize(d)?;
72
73 match value {
74 Some(val) => decode_hex_with_prefix(&val)
75 .map(Into::into)
76 .map(Some)
77 .map_err(|e| serde::de::Error::custom(e.to_string())),
78 None => Ok(None),
79 }
80 }
81}
82
83pub mod hex_hashmap_key {
85 use std::collections::HashMap;
86
87 use serde::{de, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
88
89 use super::decode_hex_with_prefix;
90 use crate::Bytes;
91
92 pub fn serialize<S, V>(x: &HashMap<Bytes, V>, s: S) -> Result<S::Ok, S::Error>
93 where
94 S: Serializer,
95 V: Serialize,
96 {
97 let mut map = s.serialize_map(Some(x.len()))?;
98 for (k, v) in x.iter() {
99 map.serialize_entry(&format!("{k:#x}"), v)?;
100 }
101 map.end()
102 }
103
104 pub fn deserialize<'de, V, D>(d: D) -> Result<HashMap<Bytes, V>, D::Error>
105 where
106 D: Deserializer<'de>,
107 V: Deserialize<'de>,
108 {
109 let interim = HashMap::<String, V>::deserialize(d)?;
110
111 interim
112 .into_iter()
113 .map(|(k, v)| {
114 let k = decode_hex_with_prefix(&k).map_err(|e| de::Error::custom(e.to_string()))?;
115 Ok((Bytes::from(k), v))
116 })
117 .collect::<Result<HashMap<_, _>, _>>()
118 }
119}
120
121pub mod hex_bytes_vec {
123 use serde::{Deserialize, Deserializer, Serialize, Serializer};
124
125 use super::decode_hex_with_prefix;
126
127 pub fn serialize<S>(list: &[Vec<u8>], s: S) -> Result<S::Ok, S::Error>
129 where
130 S: Serializer,
131 {
132 let hex_strings: Vec<String> = list
134 .iter()
135 .map(|x| format!("0x{}", hex::encode(x)))
136 .collect();
137 hex_strings.serialize(s)
138 }
139
140 pub fn deserialize<'de, D>(d: D) -> Result<Vec<Vec<u8>>, D::Error>
142 where
143 D: Deserializer<'de>,
144 {
145 let hex_strings = Vec::<String>::deserialize(d)?;
146 hex_strings
147 .into_iter()
148 .map(|s| {
149 decode_hex_with_prefix(&s).map_err(|e| serde::de::Error::custom(e.to_string()))
150 })
151 .collect()
152 }
153}
154
155pub mod hex_hashmap_value {
157 use std::collections::HashMap;
158
159 use serde::{de, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
160
161 use super::decode_hex_with_prefix;
162 use crate::Bytes;
163
164 pub fn serialize<S, K>(x: &HashMap<K, Bytes>, s: S) -> Result<S::Ok, S::Error>
165 where
166 S: Serializer,
167 K: Serialize,
168 {
169 let mut map = s.serialize_map(Some(x.len()))?;
170 for (k, v) in x.iter() {
171 map.serialize_entry(k, &format!("{v:#x}"))?;
172 }
173 map.end()
174 }
175
176 pub fn deserialize<'de, K, D>(d: D) -> Result<HashMap<K, Bytes>, D::Error>
177 where
178 D: Deserializer<'de>,
179 K: Deserialize<'de> + Eq + std::hash::Hash, {
181 let interim = HashMap::<K, String>::deserialize(d)?;
182
183 interim
184 .into_iter()
185 .map(|(k, v)| {
186 let v = decode_hex_with_prefix(&v).map_err(|e| de::Error::custom(e.to_string()))?;
187 Ok((k, Bytes::from(v)))
188 })
189 .collect::<Result<HashMap<_, _>, _>>()
190 }
191}
192
193pub mod hex_hashmap_key_value {
195 use std::collections::HashMap;
196
197 use serde::{de, ser::SerializeMap, Deserialize, Deserializer, Serializer};
198
199 use super::decode_hex_with_prefix;
200 use crate::Bytes;
201
202 pub fn serialize<S>(x: &HashMap<Bytes, Bytes>, s: S) -> Result<S::Ok, S::Error>
203 where
204 S: Serializer,
205 {
206 let mut map = s.serialize_map(Some(x.len()))?;
207 for (k, v) in x.iter() {
208 map.serialize_entry(&format!("{k:#x}"), &format!("{v:#x}"))?;
209 }
210 map.end()
211 }
212
213 pub fn deserialize<'de, D>(d: D) -> Result<HashMap<Bytes, Bytes>, D::Error>
214 where
215 D: Deserializer<'de>,
216 {
217 let interim = HashMap::<String, String>::deserialize(d)?;
218 interim
219 .into_iter()
220 .map(|(k, v)| {
221 let k = decode_hex_with_prefix(&k).map_err(|e| de::Error::custom(e.to_string()))?;
222 let v = decode_hex_with_prefix(&v).map_err(|e| de::Error::custom(e.to_string()))?;
223 Ok((k.into(), v.into()))
224 })
225 .collect::<Result<HashMap<_, _>, _>>()
226 }
227}
228
229#[cfg(test)]
230mod tests {
231 use serde::{Deserialize, Serialize};
232
233 use super::*;
234
235 #[derive(Debug, Serialize, Deserialize)]
236 struct TestStruct {
237 #[serde(with = "hex_bytes")]
238 bytes: Vec<u8>,
239
240 #[serde(with = "hex_bytes_option")]
241 bytes_option: Option<Vec<u8>>,
242
243 #[serde(with = "hex_bytes_vec")]
244 bytes_vec: Vec<Vec<u8>>,
245 }
246
247 #[test]
248 fn hex_bytes_serialize_deserialize() {
249 let test_struct = TestStruct {
250 bytes: vec![0u8; 10],
251 bytes_option: Some(vec![0u8; 10]),
252 bytes_vec: vec![vec![0, 1, 2, 3], vec![0xFF, 0xAB]],
253 };
254
255 let serialized = serde_json::to_string(&test_struct).unwrap();
257 assert_eq!(
258 serialized,
259 "{\"bytes\":\"0x00000000000000000000\",\"bytes_option\":\"0x00000000000000000000\",\"bytes_vec\":[\"0x00010203\",\"0xffab\"]}"
260 );
261
262 let deserialized: TestStruct = serde_json::from_str(&serialized).unwrap();
264 assert_eq!(deserialized.bytes, vec![0u8; 10]);
265 assert_eq!(deserialized.bytes_option, Some(vec![0u8; 10]));
266 assert_eq!(deserialized.bytes_vec, vec![vec![0, 1, 2, 3], vec![0xFF, 0xAB]]);
267 }
268
269 #[test]
270 fn hex_bytes_option_none() {
271 let test_struct =
272 TestStruct { bytes: vec![0u8; 10], bytes_option: None, bytes_vec: vec![] };
273
274 let serialized = serde_json::to_string(&test_struct).unwrap();
276 assert_eq!(
277 serialized,
278 "{\"bytes\":\"0x00000000000000000000\",\"bytes_option\":null,\"bytes_vec\":[]}"
279 );
280
281 let deserialized: TestStruct = serde_json::from_str(&serialized).unwrap();
283 assert_eq!(deserialized.bytes, vec![0u8; 10]);
284 assert_eq!(deserialized.bytes_option, None);
285 }
286}