kaspa_utils/serde_bytes/
de.rs

1use crate::hex::FromHex;
2use std::{fmt::Display, str};
3
4pub trait Deserialize<'de>: Sized + FromHex + TryFrom<&'de [u8]> {
5    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
6    where
7        D: serde::Deserializer<'de>;
8}
9
10impl<'de, T: FromHex + TryFrom<&'de [u8]>> Deserialize<'de> for T
11where
12    <T as TryFrom<&'de [u8]>>::Error: Display,
13{
14    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
15    where
16        D: serde::Deserializer<'de>,
17    {
18        if deserializer.is_human_readable() {
19            deserializer.deserialize_str(FromHexVisitor::default())
20        } else {
21            // serde::Deserialize for &[u8] is already optimized, so simply forward to that.
22            serde::Deserialize::deserialize(deserializer).and_then(|bts| T::try_from(bts).map_err(serde::de::Error::custom))
23        }
24    }
25}
26
27pub struct FromHexVisitor<'de, T: FromHex> {
28    marker: std::marker::PhantomData<T>,
29    lifetime: std::marker::PhantomData<&'de ()>,
30}
31
32impl<'de, T: FromHex> Default for FromHexVisitor<'de, T> {
33    fn default() -> Self {
34        Self { marker: Default::default(), lifetime: Default::default() }
35    }
36}
37
38impl<'de, T: FromHex> serde::de::Visitor<'de> for FromHexVisitor<'de, T> {
39    type Value = T;
40
41    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
42        write!(formatter, "string, str or slice, vec of bytes")
43    }
44    #[inline]
45    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
46    where
47        E: serde::de::Error,
48    {
49        FromHex::from_hex(v).map_err(serde::de::Error::custom)
50    }
51
52    #[inline]
53    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
54    where
55        E: serde::de::Error,
56    {
57        FromHex::from_hex(v).map_err(serde::de::Error::custom)
58    }
59
60    #[inline]
61    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
62    where
63        E: serde::de::Error,
64    {
65        FromHex::from_hex(&v).map_err(serde::de::Error::custom)
66    }
67
68    #[inline]
69    fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
70    where
71        E: serde::de::Error,
72    {
73        let str = str::from_utf8(v).map_err(serde::de::Error::custom)?;
74        FromHex::from_hex(str).map_err(serde::de::Error::custom)
75    }
76
77    #[inline]
78    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
79    where
80        E: serde::de::Error,
81    {
82        let str = str::from_utf8(v).map_err(serde::de::Error::custom)?;
83        FromHex::from_hex(str).map_err(serde::de::Error::custom)
84    }
85
86    #[inline]
87    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
88    where
89        E: serde::de::Error,
90    {
91        let str = str::from_utf8(&v).map_err(serde::de::Error::custom)?;
92        FromHex::from_hex(str).map_err(serde::de::Error::custom)
93    }
94}