1use serde::{Deserialize, Deserializer, Serializer};
2use smallvec::{smallvec, SmallVec};
3use std::fmt::Debug;
4use std::str;
5
6pub trait ToHex {
7 fn to_hex(&self) -> String;
8}
9
10pub fn serialize<S, T>(this: T, serializer: S) -> Result<S::Ok, S::Error>
11where
12 S: Serializer,
13 T: ToHex,
14{
15 let hex = this.to_hex();
16 serializer.serialize_str(&hex)
17}
18
19pub trait FromHex: Sized {
20 type Error: std::fmt::Display;
21 fn from_hex(hex_str: &str) -> Result<Self, Self::Error>;
22}
23
24pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
25where
26 D: Deserializer<'de>,
27 T: FromHex,
28{
29 use serde::de::Error;
30 let buff: &[u8] = Deserialize::deserialize(deserializer)?;
31 T::from_hex(str::from_utf8(buff).unwrap()).map_err(D::Error::custom)
32}
33
34impl ToHex for &[u8] {
37 fn to_hex(&self) -> String {
38 if self.is_empty() {
40 return "".to_string();
41 }
42
43 let mut hex = vec![0u8; self.len() * 2];
44 faster_hex::hex_encode(self, hex.as_mut_slice()).expect("The output is exactly twice the size of the input");
45 let result = unsafe { str::from_utf8_unchecked(&hex) };
46 result.to_string()
47 }
48}
49
50impl ToHex for Vec<u8> {
53 fn to_hex(&self) -> String {
54 (&**self).to_hex()
55 }
56}
57
58impl FromHex for Vec<u8> {
61 type Error = faster_hex::Error;
62 fn from_hex(hex_str: &str) -> Result<Self, Self::Error> {
63 if hex_str.is_empty() {
65 return Ok(vec![]);
66 }
67
68 let mut bytes = vec![0u8; hex_str.len() / 2];
69 faster_hex::hex_decode(hex_str.as_bytes(), bytes.as_mut_slice())?;
70 Ok(bytes)
71 }
72}
73
74#[derive(Debug, thiserror::Error)]
75pub enum FixedArrayError<const N: usize> {
76 #[error(transparent)]
77 Deserialize(#[from] faster_hex::Error),
78 #[error("unexpected length of hex string. actual: {0}")]
79 WrongLength(usize),
80}
81
82impl<const N: usize> FromHex for [u8; N] {
85 type Error = FixedArrayError<N>;
86 fn from_hex(hex_str: &str) -> Result<Self, Self::Error> {
87 let len = hex_str.len();
88 if len != N * 2 {
89 return Err(Self::Error::WrongLength(len));
90 }
91
92 let mut bytes = [0u8; N];
93 faster_hex::hex_decode(hex_str.as_bytes(), bytes.as_mut_slice())?;
94 Ok(bytes)
95 }
96}
97
98impl<A: smallvec::Array<Item = u8>> ToHex for SmallVec<A> {
101 fn to_hex(&self) -> String {
102 (&**self).to_hex()
103 }
104}
105
106impl<A: smallvec::Array<Item = u8>> FromHex for SmallVec<A> {
109 type Error = faster_hex::Error;
110 fn from_hex(hex_str: &str) -> Result<Self, Self::Error> {
111 if hex_str.is_empty() {
113 return Ok(smallvec![]);
114 }
115
116 let mut bytes: SmallVec<A> = smallvec![0u8; hex_str.len() / 2];
117 faster_hex::hex_decode(hex_str.as_bytes(), bytes.as_mut_slice())?;
118 Ok(bytes)
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn test_vec_hex_convert() {
128 let v: Vec<u8> = vec![0x0, 0xab, 0x55, 0x30, 0x1f, 0x63];
129 let k = "00ab55301f63";
130 assert_eq!(k.len(), v.len() * 2);
131 assert_eq!(k.to_string(), v.to_hex());
132 assert_eq!(Vec::from_hex(k).unwrap(), v);
133
134 assert!(Vec::from_hex("not a number").is_err());
135 assert!(Vec::from_hex("ab01").is_ok());
136
137 assert!(Vec::from_hex("ab0").is_err());
139 assert_eq!(Vec::from_hex("").unwrap().len(), 0);
141 }
142
143 #[test]
144 fn test_smallvec_hex_convert() {
145 type TestVec = SmallVec<[u8; 36]>;
146
147 let v: TestVec = smallvec![0x0, 0xab, 0x55, 0x30, 0x1f, 0x63];
148 let k = "00ab55301f63";
149 assert_eq!(k.len(), v.len() * 2);
150 assert_eq!(k.to_string(), v.to_hex());
151 assert_eq!(SmallVec::<[u8; 36]>::from_hex(k).unwrap(), v);
152
153 assert!(TestVec::from_hex("not a number").is_err());
154 assert!(TestVec::from_hex("ab01").is_ok());
155
156 assert!(TestVec::from_hex("ab0").is_err());
158 assert_eq!(TestVec::from_hex("").unwrap().len(), 0);
160 }
161}