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")]
126#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
127pub fn deserialize_hex_or_bin_vec<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
128where
129 D: Deserializer<'de>,
130{
131 if deserializer.is_human_readable() {
132 struct StrVisitor;
133
134 impl<'de> Visitor<'de> for StrVisitor {
135 type Value = Vec<u8>;
136
137 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
138 write!(formatter, "a string")
139 }
140
141 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
142 where
143 E: Error,
144 {
145 base16ct::mixed::decode_vec(v).map_err(E::custom)
146 }
147 }
148
149 deserializer.deserialize_str(StrVisitor)
150 } else {
151 Vec::deserialize(deserializer)
152 }
153}
154
155#[cfg(feature = "alloc")]
157#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
158pub type HexLowerOrBin = HexOrBin<false>;
159
160#[cfg(feature = "alloc")]
162#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
163pub type HexUpperOrBin = HexOrBin<true>;
164
165#[cfg(feature = "alloc")]
169#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
170#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
171pub struct HexOrBin<const UPPERCASE: bool>(pub Vec<u8>);
172
173#[cfg(feature = "alloc")]
174#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
175impl<const UPPERCASE: bool> AsRef<[u8]> for HexOrBin<UPPERCASE> {
176 fn as_ref(&self) -> &[u8] {
177 self.0.as_ref()
178 }
179}
180
181#[cfg(feature = "alloc")]
182#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
183impl<const UPPERCASE: bool> From<&[u8]> for HexOrBin<UPPERCASE> {
184 fn from(bytes: &[u8]) -> HexOrBin<UPPERCASE> {
185 Self(bytes.into())
186 }
187}
188
189#[cfg(feature = "alloc")]
190#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
191impl<const UPPERCASE: bool> From<Vec<u8>> for HexOrBin<UPPERCASE> {
192 fn from(vec: Vec<u8>) -> HexOrBin<UPPERCASE> {
193 Self(vec)
194 }
195}
196
197#[cfg(feature = "alloc")]
198#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
199impl<const UPPERCASE: bool> From<HexOrBin<UPPERCASE>> for Vec<u8> {
200 fn from(vec: HexOrBin<UPPERCASE>) -> Vec<u8> {
201 vec.0
202 }
203}
204
205#[cfg(feature = "alloc")]
206#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
207impl<const UPPERCASE: bool> Serialize for HexOrBin<UPPERCASE> {
208 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
209 where
210 S: Serializer,
211 {
212 if UPPERCASE {
213 serialize_hex_upper_or_bin(self, serializer)
214 } else {
215 serialize_hex_lower_or_bin(self, serializer)
216 }
217 }
218}
219
220#[cfg(feature = "alloc")]
221#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
222impl<'de, const UPPERCASE: bool> Deserialize<'de> for HexOrBin<UPPERCASE> {
223 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
224 where
225 D: Deserializer<'de>,
226 {
227 deserialize_hex_or_bin_vec(deserializer).map(Self)
228 }
229}
230
231#[cfg(all(feature = "alloc", feature = "zeroize"))]
232#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", feature = "zeroize"))))]
233impl<const UPPERCASE: bool> Zeroize for HexOrBin<UPPERCASE> {
234 fn zeroize(&mut self) {
235 self.0.as_mut_slice().zeroize();
236 }
237}