1use core::str;
3use crate::prelude::*;
5
6static HEX2DIGIT: [Option<u8>; 256] = {
7 let mut table = [None; 256];
8 let mut i = 0;
9
10 while i <= 9 {
11 table[b'0' as usize + i] = Some(i as u8);
12
13 i += 1;
14 }
15
16 i = 0;
17
18 while i <= 5 {
19 table[b'a' as usize + i] = Some((10 + i) as u8);
20 table[b'A' as usize + i] = Some((10 + i) as u8);
21
22 i += 1;
23 }
24
25 table
26};
27
28pub trait Dehexify
69where
70 Self: Sized,
71{
72 fn dehexify<H>(hex: H) -> Result<Self>
74 where
75 H: AsRef<[u8]>;
76}
77macro_rules! impl_dehexify_for_unsigned {
78 ($($t:ty,)+) => {
79 $(impl Dehexify for $t {
80 fn dehexify<H>(hex: H) -> Result<Self>
81 where
82 H: AsRef<[u8]>,
83 {
84 let hex = strip_0x(hex.as_ref());
85 let hex = str::from_utf8(hex).map_err(Error::Utf8Error)?;
86
87 Self::from_str_radix(hex, 16).map_err(Error::ParseIntError)
88 }
89 })+
90 };
91}
92impl_dehexify_for_unsigned! {
93 usize,
94 u8,
95 u16,
96 u32,
97 u64,
98 u128,
99}
100impl<const N: usize> Dehexify for [u8; N] {
101 fn dehexify<H>(hex: H) -> Result<Self>
102 where
103 H: AsRef<[u8]>,
104 {
105 dehexify_array(hex)
106 }
107}
108impl Dehexify for SmallVec<[u8; 64]> {
109 fn dehexify<H>(hex: H) -> Result<Self>
110 where
111 H: AsRef<[u8]>,
112 {
113 dehexify_bytes(hex)
114 }
115}
116impl Dehexify for Vec<u8> {
117 fn dehexify<H>(hex: H) -> Result<Self>
118 where
119 H: AsRef<[u8]>,
120 {
121 dehexify_bytes(hex).map(|sv| sv.into_vec())
122 }
123}
124#[test]
125fn dehexify_should_work() {
126 assert_eq!(u8::dehexify("34"), Ok(52));
128 assert_eq!(u16::dehexify("208"), Ok(520));
129 assert_eq!(u32::dehexify("0x4f5da2"), Ok(5_201_314));
130 assert_eq!(u64::dehexify("0x4F5DA2"), Ok(5_201_314));
131 assert_eq!(u128::dehexify("4f5da2"), Ok(5_201_314));
132 assert_eq!(usize::dehexify("4F5DA2"), Ok(5_201_314));
133 assert_eq!(
135 <[u8; 17]>::dehexify("0x4c6f7665204a616e6520466f7265766572"),
136 Ok(*b"Love Jane Forever")
137 );
138 assert_eq!(
140 SmallVec::dehexify("0x4c6f7665204a616e6520466f7265766572").unwrap().into_vec(),
141 b"Love Jane Forever".to_vec()
142 );
143 assert_eq!(SmallVec::dehexify("我爱你"), Err(Error::InvalidLength));
144 assert_eq!(SmallVec::dehexify("0x我爱你"), Err(Error::InvalidLength));
145 assert_eq!(
147 <Vec<u8>>::dehexify("0x4c6f7665204a616e6520466f7265766572"),
148 Ok(b"Love Jane Forever".to_vec())
149 );
150 assert_eq!(
151 <Vec<u8>>::dehexify("我爱你 "),
152 Err(Error::InvalidCharacter { character: 'æ', index: 0 })
153 );
154 assert_eq!(
155 <Vec<u8>>::dehexify(" 我爱你"),
156 Err(Error::InvalidCharacter { character: ' ', index: 0 })
157 );
158}
159
160pub fn dehexify_slice_mut<H>(hex: H, slice_src: &mut [u8]) -> Result<&[u8]>
173where
174 H: AsRef<[u8]>,
175{
176 let hex = strip_0x(hex.as_ref());
177
178 if hex.len() % 2 != 0 {
179 Err(Error::InvalidLength)?;
180 }
181
182 let expected_len = hex.len() >> 1;
183
184 if expected_len != slice_src.len() {
185 Err(Error::MismatchedLength { expect: expected_len })?;
186 }
187
188 for (byte, i) in slice_src.iter_mut().zip((0..hex.len()).step_by(2)) {
189 *byte = dehexify_ascii((&hex[i], i), (&hex[i + 1], i + 1))?;
190 }
191
192 Ok(slice_src)
193}
194#[test]
195fn dehexify_slice_mut_should_work() {
196 let mut bytes = [0; 17];
197 assert_eq!(
198 dehexify_slice_mut("0x4c6f7665204a616e6520466f7265766572", &mut bytes),
199 Ok(b"Love Jane Forever".as_slice())
200 );
201 assert_eq!(bytes, *b"Love Jane Forever");
202
203 let mut bytes = [0; 17];
204 assert_eq!(
205 dehexify_slice_mut("0x4c6f7665204a616e6520466f7265766572".as_bytes(), &mut bytes),
206 Ok(b"Love Jane Forever".as_slice())
207 );
208 assert_eq!(bytes, *b"Love Jane Forever");
209
210 let mut bytes = [0; 17];
211 assert_eq!(
212 dehexify_slice_mut("4c6f7665204a616e6520466f7265766572", &mut bytes),
213 Ok(b"Love Jane Forever".as_slice())
214 );
215 assert_eq!(bytes, *b"Love Jane Forever");
216
217 let mut bytes = [0; 17];
218 assert_eq!(
219 dehexify_slice_mut("4c6f7665204a616e6520466f7265766572".as_bytes(), &mut bytes),
220 Ok(b"Love Jane Forever".as_slice())
221 );
222 assert_eq!(bytes, *b"Love Jane Forever");
223
224 assert_eq!(dehexify_slice_mut("0", &mut []), Err(Error::InvalidLength));
225 assert_eq!(dehexify_slice_mut("0x0", &mut []), Err(Error::InvalidLength));
226
227 assert_eq!(dehexify_slice_mut("00", &mut []), Err(Error::MismatchedLength { expect: 1 }));
228 assert_eq!(dehexify_slice_mut("0x0001", &mut []), Err(Error::MismatchedLength { expect: 2 }));
229
230 assert_eq!(
231 dehexify_slice_mut("fg", &mut [0]),
232 Err(Error::InvalidCharacter { character: 'g', index: 1 })
233 );
234 assert_eq!(
235 dehexify_slice_mut("0xyz", &mut [0]),
236 Err(Error::InvalidCharacter { character: 'y', index: 0 })
237 );
238}
239
240pub fn dehexify_array_then_into<H, T, const N: usize>(hex: H) -> Result<T>
258where
259 H: AsRef<[u8]>,
260 T: From<[u8; N]>,
261{
262 Ok(dehexify_array(hex)?.into())
263}
264#[test]
265fn dehexify_array_then_into_should_work() {
266 assert_eq!(
267 dehexify_array_then_into::<_, Ljfn, 17>("0x4c6f7665204a616e6520466f7265766572"),
268 Ok(Ljfn(*b"Love Jane Forever"))
269 );
270 assert_eq!(
271 dehexify_array_then_into::<_, Ljfn, 17>("4c6f7665204a616e6520466f7265766572"),
272 Ok(Ljfn(*b"Love Jane Forever"))
273 );
274
275 assert_eq!(
276 dehexify_array_then_into::<_, Ljfn, 17>("0x4c6f7665204a616e6520466f7265766572".as_bytes()),
277 Ok(Ljfn(*b"Love Jane Forever"))
278 );
279 assert_eq!(
280 dehexify_array_then_into::<_, Ljfn, 17>("4c6f7665204a616e6520466f7265766572".as_bytes()),
281 Ok(Ljfn(*b"Love Jane Forever"))
282 );
283}
284
285pub fn dehexify_vec_then_into<H, T>(hex: H) -> Result<T>
303where
304 H: AsRef<[u8]>,
305 T: From<Vec<u8>>,
306{
307 Ok(dehexify_bytes(hex.as_ref())?.into_vec().into())
308}
309#[test]
310fn dehexify_vec_then_into_should_work() {
311 assert_eq!(
312 dehexify_vec_then_into::<_, Ljf>("0x4c6f7665204a616e6520466f7265766572"),
313 Ok(Ljf(b"Love Jane Forever".to_vec()))
314 );
315 assert_eq!(
316 dehexify_vec_then_into::<_, Ljf>("4c6f7665204a616e6520466f7265766572"),
317 Ok(Ljf(b"Love Jane Forever".to_vec()))
318 );
319
320 assert_eq!(
321 dehexify_vec_then_into::<_, Ljf>("0x4c6f7665204a616e6520466f7265766572".as_bytes()),
322 Ok(Ljf(b"Love Jane Forever".to_vec()))
323 );
324 assert_eq!(
325 dehexify_vec_then_into::<_, Ljf>("4c6f7665204a616e6520466f7265766572".as_bytes()),
326 Ok(Ljf(b"Love Jane Forever".to_vec()))
327 );
328}
329
330#[inline(always)]
331fn dehexify_array<H, const N: usize>(hex: H) -> Result<[u8; N]>
332where
333 H: AsRef<[u8]>,
334{
335 let bytes = dehexify_bytes(hex)?;
336
337 op::slice2array(&bytes)
338}
339
340#[inline(always)]
341fn dehexify_bytes<H>(hex: H) -> Result<SmallVec<[u8; 64]>>
342where
343 H: AsRef<[u8]>,
344{
345 let hex = strip_0x(hex.as_ref());
346
347 if hex.len() % 2 != 0 {
348 Err(Error::InvalidLength)?;
349 }
350
351 let cap = hex.len() / 2;
352 let mut bytes = <SmallVec<[u8; 64]>>::with_capacity(cap);
353
354 unsafe {
356 bytes.set_len(cap);
357 }
358
359 let bytes_ptr = bytes.as_mut_ptr();
360
361 for i in 0..cap {
362 let high = HEX2DIGIT[hex[i * 2] as usize]
363 .ok_or(Error::InvalidCharacter { character: hex[i * 2] as char, index: i * 2 })?;
364 let low = HEX2DIGIT[hex[i * 2 + 1] as usize].ok_or(Error::InvalidCharacter {
365 character: hex[i * 2 + 1] as char,
366 index: i * 2 + 1,
367 })?;
368
369 unsafe {
370 *bytes_ptr.add(i) = (high << 4) | low;
371 }
372 }
373
374 Ok(bytes)
375}
376
377#[inline(always)]
378pub(super) fn strip_0x(hex: &[u8]) -> &[u8] {
379 if hex.len() >= 2 && hex[0] == b'0' && hex[1] == b'x' {
380 &hex[2..]
381 } else {
382 hex
383 }
384}
385
386#[inline(always)]
387fn dehexify_ascii((hex0, hex0_idx): (&u8, usize), (hex1, hex1_idx): (&u8, usize)) -> Result<u8> {
388 let ascii = HEX2DIGIT[*hex0 as usize]
389 .ok_or(Error::InvalidCharacter { character: *hex0 as _, index: hex0_idx })?
390 << 4 | HEX2DIGIT[*hex1 as usize]
391 .ok_or(Error::InvalidCharacter { character: *hex1 as _, index: hex1_idx })?;
392
393 Ok(ascii)
394}