kaspa_utils/serde_bytes_fixed/
de.rs

1/// Trait for deserialization of fixed-size byte arrays, newtype structs,
2/// or any other custom types that can implement `From<[u8; N]>`.
3/// Implementers should also provide implementation for `crate::hex::FromHex`.
4/// N must be in range: (0..=32), this is serde limitation
5pub trait Deserialize<'de, const N: usize>: Sized + crate::hex::FromHex + From<[u8; N]> {
6    /// Deserialize given `deserializer` into `Self`.
7    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
8    where
9        D: serde::Deserializer<'de>;
10}
11
12/// Macro to generate impl of `Deserialize` for types `T`, which are
13/// capable of being constructed from byte arrays of fixed size,
14/// or newtype structs or other types based on [`From<[u8; $size]>`].
15macro_rules! deser_fixed_bytes {
16    ($size: expr) => {
17        impl<'de, T: $crate::hex::FromHex + From<[u8; $size]>> $crate::serde_bytes_fixed::Deserialize<'de, $size> for T {
18            /// Deserialization function for types `T`
19            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
20            where
21                D: serde::Deserializer<'de>,
22            {
23                struct FixedBytesVisitor<'de> {
24                    marker: std::marker::PhantomData<[u8; $size]>,
25                    lifetime: std::marker::PhantomData<&'de ()>,
26                }
27                impl<'de> serde::de::Visitor<'de> for FixedBytesVisitor<'de> {
28                    type Value = [u8; $size];
29
30                    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
31                        write!(formatter, "a byte array of size {}", $size)
32                    }
33                    #[inline]
34                    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
35                    where
36                        E: serde::de::Error,
37                    {
38                        let v: [u8; $size] = v.as_bytes().try_into().map_err(serde::de::Error::custom)?;
39                        Ok(Self::Value::from(v))
40                    }
41                    #[inline]
42                    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
43                    where
44                        E: serde::de::Error,
45                    {
46                        let v: [u8; $size] = v.as_bytes().try_into().map_err(serde::de::Error::custom)?;
47                        Ok(Self::Value::from(v))
48                    }
49                    #[inline]
50                    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
51                    where
52                        E: serde::de::Error,
53                    {
54                        let v: [u8; $size] = v.try_into().map_err(serde::de::Error::custom)?;
55                        Ok(Self::Value::from(v))
56                    }
57                    #[inline]
58                    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
59                    where
60                        E: serde::de::Error,
61                    {
62                        let v: [u8; $size] = v.try_into().map_err(serde::de::Error::custom)?;
63                        Ok(Self::Value::from(v))
64                    }
65
66                    #[inline]
67                    fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
68                    where
69                        D: serde::Deserializer<'de>,
70                    {
71                        <[u8; $size] as serde::Deserialize>::deserialize(deserializer).map(|v| Self::Value::from(v))
72                    }
73                    #[inline]
74                    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
75                    where
76                        A: serde::de::SeqAccess<'de>,
77                    {
78                        let Some(value): Option<[u8; $size]> = seq.next_element()? else {
79                            return Err(serde::de::Error::invalid_length(0usize, &"tuple struct fixed array with 1 element"));
80                        };
81                        Ok(Self::Value::from(value))
82                    }
83                }
84
85                if deserializer.is_human_readable() {
86                    deserializer.deserialize_str($crate::serde_bytes::FromHexVisitor::default())
87                } else {
88                    deserializer
89                        .deserialize_tuple($size, FixedBytesVisitor { marker: Default::default(), lifetime: Default::default() })
90                        .map(Into::into)
91                }
92            }
93        }
94    };
95}
96
97macro_rules! apply_deser_fixed_bytes {
98    ($($x:expr),*) => ($(deser_fixed_bytes!($x);)*)
99}
100
101apply_deser_fixed_bytes!(
102    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
103);