1#![deny(missing_docs)]
17#![no_std]
18
19extern crate alloc;
20
21use alloc::vec::Vec;
22use core::fmt::{self, Display};
23use serdapt::{DeserializeWith, SerializeWith};
24use serde::{de::Visitor, Deserializer, Serialize, Serializer};
25
26#[non_exhaustive]
50pub struct Hex<const UPPERCASE: bool = false> {}
51
52pub type LowHex = Hex<false>;
54
55pub type UpHex = Hex<true>;
57
58impl<const UPPERCASE: bool> Hex<UPPERCASE> {
59 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
61 where
62 T: ?Sized,
63 S: Serializer,
64 Self: SerializeWith<T>,
65 {
66 Self::serialize_with(value, serializer)
67 }
68
69 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
71 where
72 D: Deserializer<'de>,
73 Self: DeserializeWith<'de, T>,
74 {
75 Self::deserialize_with(deserializer)
76 }
77}
78
79impl<T> SerializeWith<T> for Hex<false>
80where
81 T: AsRef<[u8]>,
82{
83 fn serialize_with<S: Serializer>(value: &T, serializer: S) -> Result<S::Ok, S::Error> {
84 Serialize::serialize(&hex::encode(value), serializer)
85 }
86}
87
88impl<T> SerializeWith<T> for Hex<true>
89where
90 T: AsRef<[u8]>,
91{
92 fn serialize_with<S: Serializer>(value: &T, serializer: S) -> Result<S::Ok, S::Error> {
93 Serialize::serialize(&hex::encode_upper(value), serializer)
94 }
95}
96
97impl<'de, const U: bool, T> DeserializeWith<'de, T> for Hex<U>
98where
99 T: TryFrom<Vec<u8>>,
100 T::Error: Display,
101{
102 fn deserialize_with<D>(deserializer: D) -> Result<T, D::Error>
103 where
104 D: Deserializer<'de>,
105 {
106 let bytes = deserializer.deserialize_str(HexVisitor)?;
107 bytes.try_into().map_err(serde::de::Error::custom)
108 }
109}
110
111struct HexVisitor;
112
113impl Visitor<'_> for HexVisitor {
114 type Value = Vec<u8>;
115
116 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
117 f.write_str("a hex string")
118 }
119
120 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
121 where
122 E: serde::de::Error,
123 {
124 hex::decode(v).map_err(serde::de::Error::custom)
125 }
126}
127
128#[non_exhaustive]
150pub struct HexArray<const UPPERCASE: bool = false> {}
151
152pub type LowHexArray = HexArray<false>;
154
155pub type UpHexArray = HexArray<true>;
157
158impl<const U: bool> HexArray<U> {
159 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
161 where
162 T: ?Sized,
163 S: Serializer,
164 Self: SerializeWith<T>,
165 {
166 Self::serialize_with(value, serializer)
167 }
168
169 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
171 where
172 D: Deserializer<'de>,
173 Self: DeserializeWith<'de, T>,
174 {
175 Self::deserialize_with(deserializer)
176 }
177}
178
179impl<T> SerializeWith<T> for HexArray<false>
180where
181 T: AsRef<[u8]>,
182{
183 fn serialize_with<S: Serializer>(value: &T, serializer: S) -> Result<S::Ok, S::Error> {
184 Serialize::serialize(&hex::encode(value), serializer)
185 }
186}
187
188impl<T> SerializeWith<T> for HexArray<true>
189where
190 T: AsRef<[u8]>,
191{
192 fn serialize_with<S: Serializer>(value: &T, serializer: S) -> Result<S::Ok, S::Error> {
193 Serialize::serialize(&hex::encode_upper(value), serializer)
194 }
195}
196
197impl<'de, const U: bool, const N: usize> DeserializeWith<'de, [u8; N]> for HexArray<U> {
198 fn deserialize_with<D>(deserializer: D) -> Result<[u8; N], D::Error>
199 where
200 D: Deserializer<'de>,
201 {
202 deserializer.deserialize_str(HexArrayVisitor::<N>)
203 }
204}
205
206struct HexArrayVisitor<const N: usize>;
207
208impl<const N: usize> Visitor<'_> for HexArrayVisitor<N> {
209 type Value = [u8; N];
210
211 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
212 write!(f, "a hex string encoding {N} bytes")
213 }
214
215 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
216 where
217 E: serde::de::Error,
218 {
219 let mut out = [0u8; N];
220 hex::decode_to_slice(v, &mut out).map_err(|e| match e {
221 hex::FromHexError::InvalidStringLength => E::invalid_length(v.len() / 2, &self),
222 _ => E::custom(e),
223 })?;
224 Ok(out)
225 }
226}