ckb_fixed_hash_core/
serde.rs1use std::str::FromStr;
2
3use crate::{H160, H256, H512, H520};
4
5macro_rules! impl_serde {
6 ($name:ident, $bytes_size:expr) => {
7 impl serde::Serialize for $name {
8 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
9 where
10 S: serde::Serializer,
11 {
12 let bytes = &self.0[..];
13 let mut dst = [0u8; $bytes_size * 2 + 2];
14 dst[0] = b'0';
15 dst[1] = b'x';
16 faster_hex::hex_encode(bytes, &mut dst[2..])
17 .map_err(|e| serde::ser::Error::custom(format!("{e}")))?;
18 serializer.serialize_str(unsafe { ::std::str::from_utf8_unchecked(&dst) })
19 }
20 }
21
22 impl<'de> serde::Deserialize<'de> for $name {
23 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
24 where
25 D: serde::Deserializer<'de>,
26 {
27 struct Visitor;
28
29 impl<'b> serde::de::Visitor<'b> for Visitor {
30 type Value = $name;
31
32 fn expecting(
33 &self,
34 formatter: &mut ::std::fmt::Formatter,
35 ) -> ::std::fmt::Result {
36 write!(
37 formatter,
38 "a 0x-prefixed hex string with {} digits",
39 $bytes_size * 2
40 )
41 }
42
43 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
44 where
45 E: serde::de::Error,
46 {
47 let b = v.as_bytes();
48 if b.len() <= 2 || &b[0..2] != b"0x" {
49 return Err(E::custom(format_args!(
50 "invalid format, expected {}",
51 &self as &dyn serde::de::Expected
52 )));
53 }
54
55 if b.len() != $bytes_size * 2 + 2 {
56 return Err(E::invalid_length(b.len() - 2, &self));
57 }
58
59 $name::from_str(&v[2..]).map_err(|e| {
60 E::custom(format_args!(
61 "invalid hex bytes: {:?}, expected {}",
62 e, &self as &dyn serde::de::Expected
63 ))
64 })
65 }
66
67 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
68 where
69 E: serde::de::Error,
70 {
71 self.visit_str(&v)
72 }
73 }
74 deserializer.deserialize_str(Visitor)
75 }
76 }
77 };
78}
79
80impl_serde!(H160, 20);
81impl_serde!(H256, 32);
82impl_serde!(H512, 64);
83impl_serde!(H520, 65);