1use hex::FromHexError;
2
3use crate::encode::SMALL_SER_LEN;
4
5pub(crate) const SMALL_DES_LEN: usize = SMALL_SER_LEN / 2;
6
7fn fast_deserialize<V>(v: &str, out: impl FnOnce(&[u8]) -> V) -> Result<V, FromHexError> {
8 if v.len() % 2 != 0 {
9 return Err(FromHexError::OddLength);
10 }
11
12 let byte_len = v.len() / 2;
13 let mut array;
14 let mut vec;
15 let buf;
16 if byte_len <= SMALL_DES_LEN {
17 array = [0; SMALL_DES_LEN];
18 buf = &mut array[..byte_len];
19 } else {
20 vec = vec![0; byte_len];
21 buf = &mut vec[..];
22 }
23 hex::decode_to_slice(v, buf)?;
24
25 Ok(out(buf))
26}
27
28pub(crate) fn fast_deserialize_into<T>(v: &str) -> Result<T, FromHexError>
29where
30 T: for<'a> TryFrom<&'a [u8]>,
31{
32 fast_deserialize(v, |buf| {
33 T::try_from(buf).map_err(|_| FromHexError::InvalidStringLength)
34 })?
35}
36
37pub fn decode_into<T>(v: &str) -> Result<T, FromHexError>
41where
42 T: for<'a> TryFrom<&'a [u8]>,
43{
44 fast_deserialize_into(v)
45}
46
47pub fn decode<V>(v: &str, out: impl FnOnce(&[u8]) -> V) -> Result<V, FromHexError> {
52 fast_deserialize(v, out)
53}