1#[cfg(feature = "serde")]
8pub mod serde_details {
9 use core::marker::PhantomData;
10 use core::str::FromStr;
11 use core::{fmt, ops, str};
12
13 use crate::FromSliceError;
14 struct HexVisitor<ValueT>(PhantomData<ValueT>);
15 use serde::{de, Deserializer, Serializer};
16
17 impl<'de, ValueT> de::Visitor<'de> for HexVisitor<ValueT>
18 where
19 ValueT: FromStr,
20 <ValueT as FromStr>::Err: fmt::Display,
21 {
22 type Value = ValueT;
23
24 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
25 formatter.write_str("an ASCII hex string")
26 }
27
28 fn visit_bytes<E>(self, v: &[u8]) -> core::result::Result<Self::Value, E>
29 where
30 E: de::Error,
31 {
32 if let Ok(hex) = str::from_utf8(v) {
33 Self::Value::from_str(hex).map_err(E::custom)
34 } else {
35 return Err(E::invalid_value(de::Unexpected::Bytes(v), &self));
36 }
37 }
38
39 fn visit_str<E>(self, v: &str) -> core::result::Result<Self::Value, E>
40 where
41 E: de::Error,
42 {
43 Self::Value::from_str(v).map_err(E::custom)
44 }
45 }
46
47 struct BytesVisitor<ValueT>(PhantomData<ValueT>);
48
49 impl<'de, ValueT> de::Visitor<'de> for BytesVisitor<ValueT>
50 where
51 ValueT: SerdeHash,
52 <ValueT as FromStr>::Err: fmt::Display,
53 {
54 type Value = ValueT;
55
56 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
57 formatter.write_str("a bytestring")
58 }
59
60 fn visit_bytes<E>(self, v: &[u8]) -> core::result::Result<Self::Value, E>
61 where
62 E: de::Error,
63 {
64 SerdeHash::from_slice_delegated(v).map_err(|_| {
65 E::invalid_length(v.len(), &stringify!(N))
67 })
68 }
69 }
70
71 pub trait SerdeHash
73 where
74 Self: Sized
75 + FromStr
76 + fmt::Display
77 + ops::Index<usize, Output = u8>
78 + ops::Index<ops::RangeFull, Output = [u8]>,
79 <Self as FromStr>::Err: fmt::Display,
80 {
81 const N: usize;
83
84 fn from_slice_delegated(sl: &[u8]) -> core::result::Result<Self, FromSliceError>;
86
87 fn serialize<S: Serializer>(&self, s: S) -> core::result::Result<S::Ok, S::Error> {
89 if s.is_human_readable() {
90 s.collect_str(self)
91 } else {
92 s.serialize_bytes(&self[..])
93 }
94 }
95
96 fn deserialize<'de, D: Deserializer<'de>>(d: D) -> core::result::Result<Self, D::Error> {
98 if d.is_human_readable() {
99 d.deserialize_str(HexVisitor::<Self>(PhantomData))
100 } else {
101 d.deserialize_bytes(BytesVisitor::<Self>(PhantomData))
102 }
103 }
104 }
105}
106
107#[macro_export]
110#[cfg(feature = "serde")]
111macro_rules! serde_impl(
112 ($t:ident, $len:expr $(, $gen:ident: $gent:ident)*) => (
113 impl<$($gen: $gent),*> $crate::serde_macros::serde_details::SerdeHash for $t<$($gen),*> {
114 const N : usize = $len;
115 fn from_slice_delegated(sl: &[u8]) -> core::result::Result<Self, $crate::FromSliceError> {
116 $t::from_slice(sl)
117 }
118 }
119
120 impl<$($gen: $gent),*> $crate::serde::Serialize for $t<$($gen),*> {
121 fn serialize<S: $crate::serde::Serializer>(&self, s: S) -> core::result::Result<S::Ok, S::Error> {
122 $crate::serde_macros::serde_details::SerdeHash::serialize(self, s)
123 }
124 }
125
126 impl<'de $(, $gen: $gent)*> $crate::serde::Deserialize<'de> for $t<$($gen),*> {
127 fn deserialize<D: $crate::serde::Deserializer<'de>>(d: D) -> core::result::Result<$t<$($gen),*>, D::Error> {
128 $crate::serde_macros::serde_details::SerdeHash::deserialize(d)
129 }
130 }
131));
132
133#[macro_export]
135#[cfg(not(feature = "serde"))]
136macro_rules! serde_impl(
137 ($t:ident, $len:expr $(, $gen:ident: $gent:ident)*) => ()
138);