kaspa_utils/serde_bytes_fixed_ref/
ser.rs

1use serde::ser::SerializeTuple;
2use serde::Serializer;
3use std::str;
4
5/// Trait for serialization of types which can be referenced as fixed-size byte arrays.
6pub trait Serialize<const N: usize> {
7    /// Serialize `self` using the provided Serializer.
8    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
9    where
10        S: Serializer;
11}
12
13/// Implementation of Serialize trait for types that can be referenced as fixed-size byte array.
14impl<const N: usize, T: AsRef<[u8; N]>> Serialize<N> for T {
15    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
16    where
17        S: Serializer,
18    {
19        if serializer.is_human_readable() {
20            let mut hex = vec![0u8; self.as_ref().len() * 2];
21            faster_hex::hex_encode(self.as_ref(), &mut hex[..]).map_err(serde::ser::Error::custom)?;
22            serializer.serialize_str(unsafe { str::from_utf8_unchecked(&hex) })
23        } else {
24            let mut t = serializer.serialize_tuple(self.as_ref().len())?;
25            for v in self.as_ref() {
26                t.serialize_element(v)?;
27            }
28            t.end()
29        }
30    }
31}
32
33#[macro_export]
34/// Macro to generate serde::Serialize implementation for types `$t` that can be referenced as a byte array of fixed size,
35/// The resulting structure will support serialization into human-readable formats using hex encoding,
36/// as well as binary formats.
37macro_rules! serde_impl_ser_fixed_bytes_ref {
38    ($t: ty, $size: expr) => {
39        impl serde::Serialize for $t {
40            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
41            where
42                S: serde::Serializer,
43            {
44                let len = std::convert::AsRef::<[u8; $size]>::as_ref(self).len();
45                if serializer.is_human_readable() {
46                    let mut hex = vec![0u8; len * 2];
47                    faster_hex::hex_encode(&std::convert::AsRef::<[u8; $size]>::as_ref(self)[..], &mut hex[..])
48                        .map_err(serde::ser::Error::custom)?;
49                    serializer.serialize_str(unsafe { std::str::from_utf8_unchecked(&hex) })
50                } else {
51                    let mut t = serializer.serialize_tuple(len)?;
52                    for v in std::convert::AsRef::<[u8; $size]>::as_ref(self) {
53                        serde::ser::SerializeTuple::serialize_element(&mut t, v)?
54                    }
55                    serde::ser::SerializeTuple::end(t)
56                }
57            }
58        }
59    };
60}