1use core::fmt;
4
5use serde::de::{Error, Visitor};
6use serde::{Deserializer, Serialize, Serializer};
7
8#[cfg(feature = "alloc")]
9use ::{alloc::vec::Vec, serde::Deserialize};
10
11#[cfg(feature = "zeroize")]
12use zeroize::Zeroize;
13
14pub fn serialize_hex_lower_or_bin<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
17where
18 S: Serializer,
19 T: AsRef<[u8]>,
20{
21 if serializer.is_human_readable() {
22 crate::serialize_hex::<_, _, false>(value, serializer)
23 } else {
24 value.as_ref().serialize(serializer)
25 }
26}
27
28pub fn serialize_hex_upper_or_bin<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
31where
32 S: Serializer,
33 T: AsRef<[u8]>,
34{
35 if serializer.is_human_readable() {
36 crate::serialize_hex::<_, _, true>(value, serializer)
37 } else {
38 value.as_ref().serialize(serializer)
39 }
40}
41
42pub fn deserialize_hex_or_bin<'de, D>(buffer: &mut [u8], deserializer: D) -> Result<&[u8], D::Error>
46where
47 D: Deserializer<'de>,
48{
49 if deserializer.is_human_readable() {
50 struct StrVisitor<'b>(&'b mut [u8]);
51
52 impl<'de, 'b> Visitor<'de> for StrVisitor<'b> {
53 type Value = &'b [u8];
54
55 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
56 write!(
57 formatter,
58 "a string with a maximum length of {}",
59 self.0.len() * 2
60 )
61 }
62
63 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
64 where
65 E: Error,
66 {
67 base16ct::mixed::decode(v, self.0).map_err(E::custom)
69 }
70 }
71
72 deserializer.deserialize_str(StrVisitor(buffer))
73 } else {
74 struct SliceVisitor<'b>(&'b mut [u8]);
75
76 impl<'de, 'b> Visitor<'de> for SliceVisitor<'b> {
77 type Value = &'b [u8];
78
79 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
80 write!(
81 formatter,
82 "a slice with a maximum length of {}",
83 self.0.len()
84 )
85 }
86
87 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
88 where
89 E: Error,
90 {
91 if v.len() <= self.0.len() {
94 let buffer = &mut self.0[..v.len()];
95 buffer.copy_from_slice(v);
96 return Ok(buffer);
97 }
98
99 Err(E::invalid_length(v.len(), &self))
100 }
101
102 #[cfg(feature = "alloc")]
103 fn visit_byte_buf<E>(self, mut v: Vec<u8>) -> Result<Self::Value, E>
104 where
105 E: Error,
106 {
107 if v.len() <= self.0.len() {
110 let buffer = &mut self.0[..v.len()];
111 buffer.swap_with_slice(&mut v);
112 return Ok(buffer);
113 }
114
115 Err(E::invalid_length(v.len(), &self))
116 }
117 }
118
119 deserializer.deserialize_byte_buf(SliceVisitor(buffer))
120 }
121}
122
123#[cfg(feature = "alloc")]
126pub fn deserialize_hex_or_bin_vec<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
127where
128 D: Deserializer<'de>,
129{
130 if deserializer.is_human_readable() {
131 struct StrVisitor;
132
133 impl<'de> Visitor<'de> for StrVisitor {
134 type Value = Vec<u8>;
135
136 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
137 write!(formatter, "a string")
138 }
139
140 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
141 where
142 E: Error,
143 {
144 base16ct::mixed::decode_vec(v).map_err(E::custom)
145 }
146 }
147
148 deserializer.deserialize_str(StrVisitor)
149 } else {
150 Vec::deserialize(deserializer)
151 }
152}
153
154#[cfg(feature = "alloc")]
156pub type HexLowerOrBin = HexOrBin<false>;
157
158#[cfg(feature = "alloc")]
160pub type HexUpperOrBin = HexOrBin<true>;
161
162#[cfg(feature = "alloc")]
166#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
167pub struct HexOrBin<const UPPERCASE: bool>(pub Vec<u8>);
168
169#[cfg(feature = "alloc")]
170impl<const UPPERCASE: bool> AsRef<[u8]> for HexOrBin<UPPERCASE> {
171 fn as_ref(&self) -> &[u8] {
172 self.0.as_ref()
173 }
174}
175
176#[cfg(feature = "alloc")]
177impl<const UPPERCASE: bool> From<&[u8]> for HexOrBin<UPPERCASE> {
178 fn from(bytes: &[u8]) -> HexOrBin<UPPERCASE> {
179 Self(bytes.into())
180 }
181}
182
183#[cfg(feature = "alloc")]
184impl<const UPPERCASE: bool> From<Vec<u8>> for HexOrBin<UPPERCASE> {
185 fn from(vec: Vec<u8>) -> HexOrBin<UPPERCASE> {
186 Self(vec)
187 }
188}
189
190#[cfg(feature = "alloc")]
191impl<const UPPERCASE: bool> From<HexOrBin<UPPERCASE>> for Vec<u8> {
192 fn from(vec: HexOrBin<UPPERCASE>) -> Vec<u8> {
193 vec.0
194 }
195}
196
197#[cfg(feature = "alloc")]
198impl<const UPPERCASE: bool> Serialize for HexOrBin<UPPERCASE> {
199 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
200 where
201 S: Serializer,
202 {
203 if UPPERCASE {
204 serialize_hex_upper_or_bin(self, serializer)
205 } else {
206 serialize_hex_lower_or_bin(self, serializer)
207 }
208 }
209}
210
211#[cfg(feature = "alloc")]
212impl<'de, const UPPERCASE: bool> Deserialize<'de> for HexOrBin<UPPERCASE> {
213 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
214 where
215 D: Deserializer<'de>,
216 {
217 deserialize_hex_or_bin_vec(deserializer).map(Self)
218 }
219}
220
221#[cfg(all(feature = "alloc", feature = "zeroize"))]
222impl<const UPPERCASE: bool> Zeroize for HexOrBin<UPPERCASE> {
223 fn zeroize(&mut self) {
224 self.0.as_mut_slice().zeroize();
225 }
226}