1#[macro_export]
33macro_rules! byte_array_struct {
34 (
35 $visibility:vis struct $name:ident ($num:expr);
36 ) => {
37
38 #[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
39 $visibility struct $name([u8; $num]);
40
41 impl ::std::ops::Deref for $name {
42 type Target = [u8];
43
44 fn deref(&self) -> &Self::Target {
45 &self.0
46 }
47 }
48
49 impl std::str::FromStr for $name {
50 type Err = ();
51
52 fn from_str(s: &str) -> Result<Self, Self::Err> {
53 let s_hex: &str = if s.len() == $num * 2 {
54 s
55 } else if s.len() == $num * 2 + 2 && s.starts_with("0x") {
56 &s[2..]
57 } else {
58 return Err(());
59 };
60 let hex = hex::decode(s_hex).map_err(|_| ())?;
61 <$name as std::convert::TryFrom<Vec<u8>>>::try_from(hex)
62 }
63 }
64
65 impl ToString for $name {
66 fn to_string(&self) -> String {
67 hex::encode(&self.0)
68 }
69 }
70
71 impl From<[u8; $num]> for $name {
72 fn from(bytes: [u8; $num]) -> Self {
73 $name(bytes)
74 }
75 }
76
77 impl std::convert::TryFrom<&[u8]> for $name {
78 type Error = ();
79
80 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
81 if value.len() != $num {
82 return Err(());
83 }
84 let mut result: [u8; $num] = [0; $num];
85 result.copy_from_slice(value);
86 Ok(result.into())
87 }
88 }
89
90 impl std::convert::TryFrom<Vec<u8>> for $name {
91 type Error = ();
92
93 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
94 if value.len() != $num {
95 return Err(());
96 }
97 let mut result: [u8; $num] = [0; $num];
98 result.copy_from_slice(&value);
99 Ok(result.into())
100 }
101 }
102
103 impl Into<Vec<u8>> for $name {
104 fn into(self) -> Vec<u8> {
105 self.0.to_vec()
106 }
107 }
108
109 impl Into<[u8; $num]> for $name {
110 fn into(self) -> [u8; $num] {
111 self.0
112 }
113 }
114
115 __bas_with_serde!($name, $num);
117 };
118}
119
120#[cfg(not(feature = "with-serde"))]
122#[macro_export]
123macro_rules! __bas_with_serde {
124 ($name:ident, $num:expr) => {
125
126 }
127}
128
129#[cfg(feature = "with-serde")]
131#[macro_export]
132macro_rules! __bas_with_serde {
133 ($name:ident, $num:expr) => {
134 impl<'de> ::serde::Deserialize<'de> for $name {
135 fn deserialize<D>(deserializer: D) -> Result<$name, D::Error>
136 where
137 D: ::serde::Deserializer<'de>,
138 {
139 use hex::FromHex;
140 let v = String::deserialize(deserializer)
141 .and_then(|s| Vec::from_hex(s).map_err(::serde::de::Error::custom))?;
142
143 if v.len() != $num {
144 return Err(::serde::de::Error::custom(&format!(
145 "Byte array invalid length: {}",
146 v.len()
147 )));
148 }
149
150 let mut bytes = [0u8; $num];
151 bytes.copy_from_slice(&v);
152
153 Ok($name(bytes))
154 }
155 }
156
157 impl ::serde::Serialize for $name {
158 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
159 where
160 S: ::serde::Serializer,
161 {
162 use hex;
163 serializer.serialize_str(&hex::encode(&self.0))
164 }
165 }
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use std::str::FromStr;
172 use std::convert::TryFrom;
173
174 byte_array_struct!(
175 struct Bytes8(8);
176 );
177 byte_array_struct!(
178 pub struct Bytes20(20);
179 );
180 byte_array_struct!(
181 struct Bytes24 (24);
182 );
183 byte_array_struct!(
184 struct Bytes32(32);
185 );
186
187 #[test]
188 fn creates_8byte_struct() {
189 let act = Bytes8::default();
190 assert_eq!(act.0.len(), 8);
191 }
192
193 #[test]
194 fn creates_20byte_struct() {
195 let act = Bytes20::default();
196 assert_eq!(act.0.len(), 20);
197 }
198
199 #[test]
200 fn creates_24byte_struct() {
201 let act = Bytes24::default();
202 assert_eq!(act.0.len(), 24);
203 }
204
205 #[test]
206 fn creates_32byte_struct() {
207 let act = Bytes32::default();
208 assert_eq!(act.0.len(), 32);
209 }
210
211 #[test]
212 fn create_from_string() {
213 let act = Bytes20::from_str("00112233445566778899aabbccddeeff00112233").unwrap();
214 assert_eq!(act.to_string(), "00112233445566778899aabbccddeeff00112233");
215 assert_eq!(act.0.len(), 20);
216
217 let act = Bytes24::from_str("0x00112233445566778899aabbccddeeff0011223344556677").unwrap();
218 assert_eq!(act.to_string(), "00112233445566778899aabbccddeeff0011223344556677");
219 assert_eq!(act.0.len(), 24);
220 }
221
222 #[test]
223 fn fail_on_invalid_size_string() {
224 let act = Bytes20::from_str("00112233445566778899aabbccddeeff0011223344");
225 assert!(act.is_err());
226
227 let act = Bytes20::from_str("00112233445566778899aabbccddeeff001122");
228 assert!(act.is_err());
229 }
230
231 #[test]
232 fn fail_on_non_hex_string() {
233 let act = Bytes20::from_str("00112233445566778899aabbccddeeff1234qwer");
234 assert!(act.is_err());
235
236 let act = Bytes20::from_str("0_00112233445566778899aabbccddeeff00112233");
237 assert!(act.is_err());
238 }
239
240 #[test]
241 fn fail_on_empty_string() {
242 let act = Bytes20::from_str("");
243 assert!(act.is_err());
244 }
245
246 #[test]
247 fn create_from_bytes() {
248 let input = hex::decode("00112233445566778899aabbccddeeff00112233").unwrap();
249 let input = input.as_slice();
250 let act = Bytes20::try_from(input).unwrap();
251 assert_eq!(act.to_string(), "00112233445566778899aabbccddeeff00112233");
252 assert_eq!(act.0.len(), 20);
253 }
254
255 #[test]
256 fn create_from_vec() {
257 let input = hex::decode("00112233445566778899aabbccddeeff00112233").unwrap();
258 let act = Bytes20::try_from(input).unwrap();
259 assert_eq!(act.to_string(), "00112233445566778899aabbccddeeff00112233");
260 assert_eq!(act.0.len(), 20);
261 }
262
263 #[test]
264 fn fail_to_create_incorrect_arr() {
265 let input = hex::decode("00112233445566778899aabbccddeeff").unwrap();
266 let act = Bytes20::try_from(input.as_slice());
267 assert!(act.is_err());
268
269 let input = hex::decode("00112233445566778899aabbccddeeff00112233").unwrap();
270 let act = Bytes8::try_from(input.as_slice());
271 assert!(act.is_err());
272 }
273
274 #[test]
275 fn fail_to_create_incorrect_vec() {
276 let input = hex::decode("00112233445566778899aabbccddeeff").unwrap();
277 let act = Bytes20::try_from(input);
278 assert!(act.is_err());
279
280 let input = hex::decode("00112233445566778899aabbccddeeff00112233").unwrap();
281 let act = Bytes8::try_from(input);
282 assert!(act.is_err());
283 }
284
285 #[test]
286 fn convert_into_vec() {
287 let input = hex::decode("00112233445566778899aabbccddeeff00112233").unwrap();
288 let act = Bytes20::try_from(input.clone()).unwrap();
289 let output: Vec<u8> = act.into();
290 assert_eq!(output, input);
291 }
292
293 #[test]
294 fn convert_into_arr() {
295 let input = hex::decode("00112233445566778899aabbccddeeff00112233").unwrap();
296 let act = Bytes20::try_from(input.clone()).unwrap();
297 let output: [u8; 20] = act.into();
298 assert_eq!(output, input.as_slice());
299 }
300}
301
302#[cfg(all(test, feature = "with-serde"))]
303mod tests_serde {
304
305 byte_array_struct!(
306 struct Hex8(8);
307 );
308
309 #[test]
310 fn encode_default_byte_array() {
311 assert_eq!(
312 serde_json::to_string(&Hex8::default()).unwrap(),
313 "\"0000000000000000\""
314 );
315 }
316
317 #[test]
318 fn decode_zero_byte_array() {
319 assert_eq!(
320 serde_json::from_str::<Hex8>("\"0000000000000000\"").unwrap(),
321 Hex8::default()
322 );
323 }
324
325 #[test]
326 fn encode_byte_array() {
327 let hex = Hex8::from([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
328
329 assert_eq!(serde_json::to_string(&hex).unwrap(), "\"0123456789abcdef\"");
330 }
331
332 #[test]
333 fn decode_byte_array() {
334 let hex = Hex8::from([0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]);
335
336 assert_eq!(
337 serde_json::from_str::<Hex8>("\"0123456789abcdef\"").unwrap(),
338 hex
339 );
340 }
341
342 #[test]
343 fn not_decode_invalid_byte_array() {
344 assert!(serde_json::from_str::<Hex8>("\"__23456789abcdef\"").is_err());
345 }
346
347 #[test]
348 fn not_decode_insufficient_byte_array() {
349 assert!(serde_json::from_str::<Hex8>("1234567890").is_err());
350 }
351
352 #[test]
353 fn not_decode_empty_text() {
354 assert!(serde_json::from_str::<Hex8>("\"\"").is_err());
355 }
356
357 #[test]
358 fn not_decode_absent_text() {
359 assert!(serde_json::from_str::<Hex8>("").is_err());
360 }
361}