kaspa_utils/serde_bytes_fixed_ref/
de.rs

1#[macro_export]
2/// Macro to provide serde::Deserialize implementations for types `$t`
3/// which can be constructed from byte arrays of fixed size.
4/// The resulting structure will support deserialization from human-readable
5/// formats using hex::FromHex, as well as binary formats.
6macro_rules! serde_impl_deser_fixed_bytes_ref {
7    ($t: ty, $size: expr) => {
8        impl<'de> serde::Deserialize<'de> for $t {
9            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
10            where
11                D: serde::Deserializer<'de>,
12            {
13                struct MyVisitor<'de> {
14                    marker: std::marker::PhantomData<$t>,
15                    lifetime: std::marker::PhantomData<&'de ()>,
16                }
17                impl<'de> serde::de::Visitor<'de> for MyVisitor<'de> {
18                    type Value = $t;
19
20                    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
21                        write!(formatter, "a byte array of size {} to ", $size)?;
22                        write!(formatter, "{}", stringify!($t))
23                    }
24                    #[inline]
25                    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
26                    where
27                        E: serde::de::Error,
28                    {
29                        let v: [u8; $size] = v.as_bytes().try_into().map_err(serde::de::Error::custom)?;
30                        Ok(Self::Value::from(v))
31                    }
32                    #[inline]
33                    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
34                    where
35                        E: serde::de::Error,
36                    {
37                        let v: [u8; $size] = v.as_bytes().try_into().map_err(serde::de::Error::custom)?;
38                        Ok(Self::Value::from(v))
39                    }
40                    #[inline]
41                    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
42                    where
43                        E: serde::de::Error,
44                    {
45                        let v: [u8; $size] = v.try_into().map_err(serde::de::Error::custom)?;
46                        Ok(Self::Value::from(v))
47                    }
48                    #[inline]
49                    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
50                    where
51                        E: serde::de::Error,
52                    {
53                        let v: [u8; $size] = v.try_into().map_err(serde::de::Error::custom)?;
54                        Ok(Self::Value::from(v))
55                    }
56
57                    #[inline]
58                    fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
59                    where
60                        D: serde::Deserializer<'de>,
61                    {
62                        <[u8; $size] as serde::Deserialize>::deserialize(deserializer).map(|v| Self::Value::from(v))
63                    }
64                    #[inline]
65                    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
66                    where
67                        A: serde::de::SeqAccess<'de>,
68                    {
69                        let Some(value): Option<[u8; $size]> = seq.next_element()? else {
70                            return Err(serde::de::Error::invalid_length(0usize, &"tuple struct fixed array with 1 element"));
71                        };
72                        Ok(Self::Value::from(value))
73                    }
74                }
75                if deserializer.is_human_readable() {
76                    deserializer.deserialize_str($crate::serde_bytes::FromHexVisitor::default())
77                } else {
78                    deserializer.deserialize_newtype_struct(
79                        stringify!($i),
80                        MyVisitor { marker: Default::default(), lifetime: Default::default() },
81                    )
82                }
83            }
84        }
85    };
86}