1use std::{collections::HashMap, fmt, hash::Hash, marker::PhantomData};
2
3use hex::FromHexError;
4use serde::{de, Deserialize, Deserializer};
5
6use crate::Bytes;
7
8fn decode_hex_with_prefix(val: &str) -> Result<Vec<u8>, FromHexError> {
11 let digits = val
12 .strip_prefix("0x")
13 .unwrap_or(val)
14 .as_bytes();
15 let mut out = vec![0u8; digits.len().div_ceil(2)];
16 if digits.len().is_multiple_of(2) {
17 hex::decode_to_slice(digits, &mut out)?;
18 } else if let (Some((first, rest)), Some((first_out, rest_out))) =
19 (digits.split_first(), out.split_first_mut())
20 {
21 hex::decode_to_slice([b'0', *first], std::slice::from_mut(first_out))?;
22 hex::decode_to_slice(rest, rest_out)?;
23 }
24 Ok(out)
25}
26
27struct HexValue(Vec<u8>);
30
31impl<'de> Deserialize<'de> for HexValue {
32 fn deserialize<D>(d: D) -> Result<Self, D::Error>
33 where
34 D: Deserializer<'de>,
35 {
36 struct HexVisitor;
37
38 impl de::Visitor<'_> for HexVisitor {
39 type Value = HexValue;
40
41 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 f.write_str("a hex string")
43 }
44
45 fn visit_str<E: de::Error>(self, value: &str) -> Result<HexValue, E> {
46 decode_hex_with_prefix(value)
47 .map(HexValue)
48 .map_err(|e| E::custom(e.to_string()))
49 }
50 }
51
52 d.deserialize_str(HexVisitor)
53 }
54}
55
56impl From<HexValue> for Bytes {
57 fn from(value: HexValue) -> Self {
58 Bytes::from(value.0)
59 }
60}
61
62fn deserialize_map<'de, D, KR, VR, K, V>(d: D) -> Result<HashMap<K, V>, D::Error>
65where
66 D: Deserializer<'de>,
67 KR: Deserialize<'de> + Into<K>,
68 VR: Deserialize<'de> + Into<V>,
69 K: Eq + Hash,
70{
71 struct MapVisitor<KR, VR, K, V>(PhantomData<(KR, VR, K, V)>);
72
73 impl<'de, KR, VR, K, V> de::Visitor<'de> for MapVisitor<KR, VR, K, V>
74 where
75 KR: Deserialize<'de> + Into<K>,
76 VR: Deserialize<'de> + Into<V>,
77 K: Eq + Hash,
78 {
79 type Value = HashMap<K, V>;
80
81 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
82 f.write_str("a map")
83 }
84
85 fn visit_map<A: de::MapAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
86 let mut map = HashMap::with_capacity(access.size_hint().unwrap_or(0));
87 while let Some((key, value)) = access.next_entry::<KR, VR>()? {
88 map.insert(key.into(), value.into());
89 }
90 Ok(map)
91 }
92 }
93
94 d.deserialize_map(MapVisitor::<KR, VR, K, V>(PhantomData))
95}
96
97#[derive(Default)]
102struct HexBuffer(Vec<u8>);
103
104impl HexBuffer {
105 fn encode<E: serde::ser::Error>(&mut self, bytes: &[u8]) -> Result<&str, E> {
112 let hex_len = bytes
113 .len()
114 .checked_mul(2)
115 .and_then(|digits| digits.checked_add(2))
116 .ok_or_else(|| {
117 E::custom(format!("cannot hex encode {} bytes: length overflows", bytes.len()))
118 })?;
119 self.0.clear();
120 self.0.extend_from_slice(b"0x");
121 self.0.resize(hex_len, 0);
122 let digits = self
123 .0
124 .get_mut(2..)
125 .ok_or_else(|| E::custom("hex buffer is shorter than its prefix"))?;
126 hex::encode_to_slice(bytes, digits).map_err(E::custom)?;
127 std::str::from_utf8(&self.0).map_err(E::custom)
128 }
129}
130
131pub mod hex_bytes {
133 use serde::{Deserialize, Deserializer, Serializer};
134
135 use super::{HexBuffer, HexValue};
136
137 pub fn serialize<S, T>(x: T, s: S) -> Result<S::Ok, S::Error>
139 where
140 S: Serializer,
141 T: AsRef<[u8]>,
142 {
143 s.serialize_str(HexBuffer::default().encode(x.as_ref())?)
144 }
145
146 pub fn deserialize<'de, T, D>(d: D) -> Result<T, D::Error>
149 where
150 D: Deserializer<'de>,
151 T: From<Vec<u8>>,
152 {
153 HexValue::deserialize(d).map(|value| value.0.into())
154 }
155}
156
157pub mod hex_bytes_option {
159 use serde::{Deserialize, Deserializer, Serializer};
160
161 use super::{HexBuffer, HexValue};
162
163 pub fn serialize<S, T>(x: &Option<T>, s: S) -> Result<S::Ok, S::Error>
165 where
166 S: Serializer,
167 T: AsRef<[u8]>,
168 {
169 if let Some(x) = x {
170 s.serialize_str(HexBuffer::default().encode(x.as_ref())?)
171 } else {
172 s.serialize_none()
173 }
174 }
175
176 pub fn deserialize<'de, T, D>(d: D) -> Result<Option<T>, D::Error>
179 where
180 D: Deserializer<'de>,
181 T: From<Vec<u8>>,
182 {
183 let value: Option<HexValue> = Option::deserialize(d)?;
184 Ok(value.map(|value| value.0.into()))
185 }
186}
187
188pub mod hex_hashmap_key {
190 use std::collections::HashMap;
191
192 use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
193
194 use super::{deserialize_map, HexBuffer, HexValue};
195 use crate::Bytes;
196
197 pub fn serialize<S, V>(x: &HashMap<Bytes, V>, s: S) -> Result<S::Ok, S::Error>
198 where
199 S: Serializer,
200 V: Serialize,
201 {
202 let mut key_hex = HexBuffer::default();
203 let mut map = s.serialize_map(Some(x.len()))?;
204 for (k, v) in x.iter() {
205 map.serialize_entry(key_hex.encode(k)?, v)?;
206 }
207 map.end()
208 }
209
210 pub fn deserialize<'de, V, D>(d: D) -> Result<HashMap<Bytes, V>, D::Error>
211 where
212 D: Deserializer<'de>,
213 V: Deserialize<'de>,
214 {
215 deserialize_map::<D, HexValue, V, Bytes, V>(d)
216 }
217}
218
219pub mod hex_bytes_vec {
221 use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serializer};
222
223 use super::{HexBuffer, HexValue};
224
225 pub fn serialize<S>(list: &[Vec<u8>], s: S) -> Result<S::Ok, S::Error>
227 where
228 S: Serializer,
229 {
230 let mut hex = HexBuffer::default();
231 let mut seq = s.serialize_seq(Some(list.len()))?;
232 for x in list {
233 seq.serialize_element(hex.encode(x)?)?;
234 }
235 seq.end()
236 }
237
238 pub fn deserialize<'de, D>(d: D) -> Result<Vec<Vec<u8>>, D::Error>
240 where
241 D: Deserializer<'de>,
242 {
243 let values = Vec::<HexValue>::deserialize(d)?;
244 Ok(values
245 .into_iter()
246 .map(|value| value.0)
247 .collect())
248 }
249}
250
251pub mod hex_hashmap_value {
253 use std::collections::HashMap;
254
255 use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
256
257 use super::{deserialize_map, HexBuffer, HexValue};
258 use crate::Bytes;
259
260 pub fn serialize<S, K>(x: &HashMap<K, Bytes>, s: S) -> Result<S::Ok, S::Error>
261 where
262 S: Serializer,
263 K: Serialize,
264 {
265 let mut value_hex = HexBuffer::default();
266 let mut map = s.serialize_map(Some(x.len()))?;
267 for (k, v) in x.iter() {
268 map.serialize_entry(k, value_hex.encode(v)?)?;
269 }
270 map.end()
271 }
272
273 pub fn deserialize<'de, K, D>(d: D) -> Result<HashMap<K, Bytes>, D::Error>
274 where
275 D: Deserializer<'de>,
276 K: Deserialize<'de> + Eq + std::hash::Hash, {
278 deserialize_map::<D, K, HexValue, K, Bytes>(d)
279 }
280}
281
282pub mod hex_hashmap_key_value {
284 use std::collections::HashMap;
285
286 use serde::{ser::SerializeMap, Deserializer, Serializer};
287
288 use super::{deserialize_map, HexBuffer, HexValue};
289 use crate::Bytes;
290
291 pub fn serialize<S>(x: &HashMap<Bytes, Bytes>, s: S) -> Result<S::Ok, S::Error>
292 where
293 S: Serializer,
294 {
295 let (mut key_hex, mut value_hex) = (HexBuffer::default(), HexBuffer::default());
296 let mut map = s.serialize_map(Some(x.len()))?;
297 for (k, v) in x.iter() {
298 map.serialize_entry(key_hex.encode(k)?, value_hex.encode(v)?)?;
299 }
300 map.end()
301 }
302
303 pub fn deserialize<'de, D>(d: D) -> Result<HashMap<Bytes, Bytes>, D::Error>
304 where
305 D: Deserializer<'de>,
306 {
307 deserialize_map::<D, HexValue, HexValue, Bytes, Bytes>(d)
308 }
309}
310
311#[cfg(test)]
312mod tests {
313 use std::collections::HashMap;
314
315 use serde::{Deserialize, Serialize};
316
317 use super::*;
318 use crate::Bytes;
319
320 #[derive(Debug, Serialize, Deserialize)]
321 struct TestStruct {
322 #[serde(with = "hex_bytes")]
323 bytes: Vec<u8>,
324
325 #[serde(with = "hex_bytes_option")]
326 bytes_option: Option<Vec<u8>>,
327
328 #[serde(with = "hex_bytes_vec")]
329 bytes_vec: Vec<Vec<u8>>,
330 }
331
332 #[test]
333 fn hex_bytes_serialize_deserialize() {
334 let test_struct = TestStruct {
335 bytes: vec![0u8; 10],
336 bytes_option: Some(vec![0u8; 10]),
337 bytes_vec: vec![vec![0, 1, 2, 3], vec![0xFF, 0xAB]],
338 };
339
340 let serialized = serde_json::to_string(&test_struct).unwrap();
342 assert_eq!(
343 serialized,
344 "{\"bytes\":\"0x00000000000000000000\",\"bytes_option\":\"0x00000000000000000000\",\"bytes_vec\":[\"0x00010203\",\"0xffab\"]}"
345 );
346
347 let deserialized: TestStruct = serde_json::from_str(&serialized).unwrap();
349 assert_eq!(deserialized.bytes, vec![0u8; 10]);
350 assert_eq!(deserialized.bytes_option, Some(vec![0u8; 10]));
351 assert_eq!(deserialized.bytes_vec, vec![vec![0, 1, 2, 3], vec![0xFF, 0xAB]]);
352 }
353
354 #[test]
355 fn hex_bytes_option_none() {
356 let test_struct =
357 TestStruct { bytes: vec![0u8; 10], bytes_option: None, bytes_vec: vec![] };
358
359 let serialized = serde_json::to_string(&test_struct).unwrap();
361 assert_eq!(
362 serialized,
363 "{\"bytes\":\"0x00000000000000000000\",\"bytes_option\":null,\"bytes_vec\":[]}"
364 );
365
366 let deserialized: TestStruct = serde_json::from_str(&serialized).unwrap();
368 assert_eq!(deserialized.bytes, vec![0u8; 10]);
369 assert_eq!(deserialized.bytes_option, None);
370 }
371
372 mod reference {
374 use std::collections::HashMap;
375
376 use serde::{ser::SerializeMap, Serialize, Serializer};
377
378 use crate::Bytes;
379
380 pub fn hex(x: &[u8]) -> String {
381 format!("0x{}", hex::encode(x))
382 }
383
384 pub fn hex_bytes<S: Serializer>(x: &[u8], s: S) -> Result<S::Ok, S::Error> {
385 s.serialize_str(&hex(x))
386 }
387
388 pub fn hex_bytes_option<S: Serializer>(
389 x: &Option<Vec<u8>>,
390 s: S,
391 ) -> Result<S::Ok, S::Error> {
392 match x {
393 Some(x) => s.serialize_str(&hex(x)),
394 None => s.serialize_none(),
395 }
396 }
397
398 pub fn hex_bytes_vec<S: Serializer>(list: &[Vec<u8>], s: S) -> Result<S::Ok, S::Error> {
399 list.iter()
400 .map(|x| hex(x))
401 .collect::<Vec<_>>()
402 .serialize(s)
403 }
404
405 pub fn hex_hashmap_key<S: Serializer>(
406 x: &HashMap<Bytes, Bytes>,
407 s: S,
408 ) -> Result<S::Ok, S::Error> {
409 let mut map = s.serialize_map(Some(x.len()))?;
410 for (k, v) in x.iter() {
411 map.serialize_entry(&format!("{k:#x}"), v)?;
412 }
413 map.end()
414 }
415
416 pub fn hex_hashmap_value<S: Serializer>(
417 x: &HashMap<Bytes, Bytes>,
418 s: S,
419 ) -> Result<S::Ok, S::Error> {
420 let mut map = s.serialize_map(Some(x.len()))?;
421 for (k, v) in x.iter() {
422 map.serialize_entry(k, &format!("{v:#x}"))?;
423 }
424 map.end()
425 }
426
427 pub fn hex_hashmap_key_value<S: Serializer>(
428 x: &HashMap<Bytes, Bytes>,
429 s: S,
430 ) -> Result<S::Ok, S::Error> {
431 let mut map = s.serialize_map(Some(x.len()))?;
432 for (k, v) in x.iter() {
433 map.serialize_entry(&format!("{k:#x}"), &format!("{v:#x}"))?;
434 }
435 map.end()
436 }
437
438 pub fn decode(val: &str) -> Result<Vec<u8>, hex::FromHexError> {
440 let mut digits: String = val
441 .strip_prefix("0x")
442 .unwrap_or(val)
443 .into();
444 if !digits.len().is_multiple_of(2) {
445 digits.insert(0, '0');
446 }
447 hex::decode(&digits)
448 }
449 }
450
451 #[derive(Serialize)]
452 struct CurrentBytes<'a> {
453 #[serde(with = "hex_bytes")]
454 bytes: &'a Vec<u8>,
455 #[serde(with = "hex_bytes_option")]
456 bytes_option: &'a Option<Vec<u8>>,
457 #[serde(with = "hex_bytes_vec")]
458 bytes_vec: &'a Vec<Vec<u8>>,
459 }
460
461 #[derive(Serialize)]
462 struct ReferenceBytes<'a> {
463 #[serde(serialize_with = "reference::hex_bytes")]
464 bytes: &'a Vec<u8>,
465 #[serde(serialize_with = "reference::hex_bytes_option")]
466 bytes_option: &'a Option<Vec<u8>>,
467 #[serde(serialize_with = "reference::hex_bytes_vec")]
468 bytes_vec: &'a Vec<Vec<u8>>,
469 }
470
471 #[derive(Serialize)]
472 struct CurrentMaps<'a> {
473 #[serde(with = "hex_hashmap_key")]
474 key: &'a HashMap<Bytes, Bytes>,
475 #[serde(with = "hex_hashmap_value")]
476 value: &'a HashMap<Bytes, Bytes>,
477 #[serde(with = "hex_hashmap_key_value")]
478 key_value: &'a HashMap<Bytes, Bytes>,
479 }
480
481 #[derive(Serialize)]
482 struct ReferenceMaps<'a> {
483 #[serde(serialize_with = "reference::hex_hashmap_key")]
484 key: &'a HashMap<Bytes, Bytes>,
485 #[serde(serialize_with = "reference::hex_hashmap_value")]
486 value: &'a HashMap<Bytes, Bytes>,
487 #[serde(serialize_with = "reference::hex_hashmap_key_value")]
488 key_value: &'a HashMap<Bytes, Bytes>,
489 }
490
491 fn hex_cases() -> Vec<Vec<u8>> {
494 let long = |len: usize| {
495 (0..len)
496 .map(|i| (i * 31 % 256) as u8)
497 .collect()
498 };
499 vec![
500 vec![],
501 vec![0],
502 vec![0x0a],
503 vec![0xff],
504 vec![0, 0, 1],
505 vec![0xff; 32],
506 (0..32).collect(),
507 long(33),
508 long(24_576),
509 long(24_577),
510 long((1 << 17) + 3),
511 ]
512 }
513
514 #[test]
515 fn hex_bytes_serializers_write_the_same_json_as_formatting_each_value() {
516 let cases = hex_cases();
517 for value in &cases {
518 let option = Some(value.clone());
519 let current = CurrentBytes { bytes: value, bytes_option: &option, bytes_vec: &cases };
520 let reference =
521 ReferenceBytes { bytes: value, bytes_option: &option, bytes_vec: &cases };
522
523 assert!(
524 serde_json::to_vec(¤t).unwrap() == serde_json::to_vec(&reference).unwrap(),
525 "output differs for a {}-byte value",
526 value.len()
527 );
528 }
529 }
530
531 #[test]
532 fn hex_hashmap_serializers_write_the_same_json_as_formatting_each_entry() {
533 let cases = hex_cases();
534 let mut map = HashMap::new();
537 for (i, key) in cases.iter().enumerate() {
538 for value in &cases {
539 let mut key = key.clone();
540 key.push(i as u8);
541 key.extend_from_slice(&value[..value.len().min(40)]);
542 map.insert(Bytes::from(key), Bytes::from(value.clone()));
543 }
544 }
545
546 let current = CurrentMaps { key: &map, value: &map, key_value: &map };
547 let reference = ReferenceMaps { key: &map, value: &map, key_value: &map };
548
549 assert!(serde_json::to_vec(¤t).unwrap() == serde_json::to_vec(&reference).unwrap());
550 }
551
552 #[test]
553 fn hex_serializers_round_trip_long_values() {
554 let test_struct = TestStruct {
555 bytes: hex_cases().pop().unwrap(),
556 bytes_option: Some(vec![]),
557 bytes_vec: hex_cases(),
558 };
559
560 let serialized = serde_json::to_string(&test_struct).unwrap();
561 let deserialized: TestStruct = serde_json::from_str(&serialized).unwrap();
562
563 assert_eq!(deserialized.bytes, test_struct.bytes);
564 assert_eq!(deserialized.bytes_option, Some(vec![]));
565 assert_eq!(deserialized.bytes_vec, test_struct.bytes_vec);
566 }
567
568 fn hex_strings() -> Vec<String> {
571 let mut strings = vec![];
572 for value in hex_cases() {
573 let digits = hex::encode(&value);
574 for digits in [digits.clone(), digits.to_uppercase()] {
575 strings.push(format!("0x{digits}"));
576 strings.push(digits.clone());
577 if let Some(odd) = digits.strip_prefix('0') {
578 strings.push(format!("0x{odd}"));
579 strings.push(odd.to_string());
580 }
581 }
582 }
583 strings
584 }
585
586 #[test]
587 fn decode_hex_with_prefix_reads_the_same_bytes_as_the_reference_decoder() {
588 for string in hex_strings() {
589 assert_eq!(
590 decode_hex_with_prefix(&string).unwrap(),
591 reference::decode(&string).unwrap(),
592 "differs for {}",
593 &string[..string.len().min(20)]
594 );
595 }
596 }
597
598 #[test]
599 fn decode_hex_with_prefix_rejects_what_the_reference_decoder_rejects() {
600 for string in ["0xzz", "0x1g", "0xg", "g", "0x0x", "é", "0xé", "0x0é", "é0", "0x é", "0x-1"]
601 {
602 assert!(reference::decode(string).is_err(), "reference accepts {string}");
603 assert!(decode_hex_with_prefix(string).is_err(), "accepts {string}");
604 }
605 }
606
607 #[derive(Debug, PartialEq, Deserialize)]
608 struct DecodedMaps {
609 #[serde(with = "hex_hashmap_key")]
610 key: HashMap<Bytes, u64>,
611 #[serde(with = "hex_hashmap_value")]
612 value: HashMap<String, Bytes>,
613 #[serde(with = "hex_hashmap_key_value")]
614 key_value: HashMap<Bytes, Bytes>,
615 }
616
617 #[test]
618 fn hex_deserializers_read_borrowed_escaped_and_owned_strings() {
619 let json = r#"{
622 "key": {"0x0a": 1, "\u0030x0b": 2},
623 "value": {"a": "0x0c", "b": "\u0030x0d"},
624 "key_value": {"0x01": "0x0002", "3": "0xff", "\u0030x04": "0x"}
625 }"#;
626 let expected = DecodedMaps {
627 key: HashMap::from([(Bytes::from(vec![0x0a]), 1), (Bytes::from(vec![0x0b]), 2)]),
628 value: HashMap::from([
629 ("a".to_string(), Bytes::from(vec![0x0c])),
630 ("b".to_string(), Bytes::from(vec![0x0d])),
631 ]),
632 key_value: HashMap::from([
633 (Bytes::from(vec![0x01]), Bytes::from(vec![0x00, 0x02])),
634 (Bytes::from(vec![0x03]), Bytes::from(vec![0xff])),
635 (Bytes::from(vec![0x04]), Bytes::from(vec![])),
636 ]),
637 };
638
639 let from_str: DecodedMaps = serde_json::from_str(json).unwrap();
640 let from_reader: DecodedMaps = serde_json::from_reader(json.as_bytes()).unwrap();
641 let value: serde_json::Value = serde_json::from_str(json).unwrap();
642 let from_value: DecodedMaps = serde_json::from_value(value).unwrap();
643
644 assert_eq!(from_str, expected);
645 assert_eq!(from_reader, expected);
646 assert_eq!(from_value, expected);
647 }
648
649 #[test]
650 fn hex_deserializers_reject_invalid_hex_and_non_strings() {
651 let invalid = [
652 r#"{"key": {"0xzz": 1}, "value": {}, "key_value": {}}"#,
653 r#"{"key": {}, "value": {"a": "0x1g"}, "key_value": {}}"#,
654 r#"{"key": {}, "value": {}, "key_value": {"0x01": "é"}}"#,
655 r#"{"key": {}, "value": {"a": 1}, "key_value": {}}"#,
656 ];
657 for json in invalid {
658 assert!(serde_json::from_str::<DecodedMaps>(json).is_err(), "accepts {json}");
659 }
660 assert!(serde_json::from_str::<TestStruct>(
661 r#"{"bytes": 1, "bytes_option": null, "bytes_vec": []}"#
662 )
663 .is_err());
664 }
665}