1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#![no_std]
#[macro_export]
macro_rules! hex {
($arg:expr) => {{
const SPACE: u8 = 32;
const NUM_SPACES: usize = {
let data = $arg.as_bytes();
let mut space_count: usize = 0;
let mut char_index: usize = 0;
while char_index < data.len() {
if data[char_index] == SPACE {
space_count += 1;
}
char_index += 1;
}
space_count
};
["Odd number of hex digits provided."][(($arg.len() - NUM_SPACES) % 2) as usize];
const ARRAY_LENGTH: usize = ($arg.len() - NUM_SPACES) / 2;
const RESULT: [u8; ARRAY_LENGTH] = {
const fn always_true() -> bool {
true
}
const fn to_ordinal(input: u8) -> u8 {
const ZERO: u8 = 48;
const NINE: u8 = 57;
const UPPER_A: u8 = 65;
const UPPER_F: u8 = 70;
const LOWER_A: u8 = 97;
const LOWER_F: u8 = 102;
match input {
ZERO..=NINE => input - '0' as u8,
UPPER_A..=UPPER_F => input - 'A' as u8 + 10,
LOWER_A..=LOWER_F => input - 'a' as u8 + 10,
_ => {
["Invalid hex digit."][(always_true() as usize)];
0
}
}
}
const fn convert(s: &str) -> [u8; ARRAY_LENGTH] {
let s = s.as_bytes();
let mut data = [0u8; ARRAY_LENGTH];
let mut data_index: usize = 0;
let mut char_index: usize = 0;
let string_length = s.len();
while data_index < string_length && char_index + 1 < string_length {
if s[char_index] != SPACE {
data[data_index] =
to_ordinal(s[char_index]) * 16 + to_ordinal(s[char_index + 1]);
char_index += 2;
data_index += 1;
} else {
char_index += 1;
}
}
data
}
convert($arg)
};
RESULT
}};
}
#[cfg(test)]
mod tests {
use super::hex;
#[test]
fn test_leading_zeros() {
assert_eq!(hex!("01020304"), [1, 2, 3, 4]);
}
#[test]
fn test_alphanumeric_lower() {
assert_eq!(hex!("a1b2c3d4"), [0xA1, 0xB2, 0xC3, 0xD4]);
}
#[test]
fn test_alphanumeric_upper() {
assert_eq!(hex!("E5E69092"), [0xE5, 0xE6, 0x90, 0x92]);
}
#[test]
fn test_alphanumeric_mixed() {
assert_eq!(hex!("0a0B0C0d"), [10, 11, 12, 13]);
}
#[test]
fn test_leading_zeros_space() {
assert_eq!(hex!("01 02 03 04"), [1, 2, 3, 4]);
}
#[test]
fn test_alphanumeric_lower_space() {
assert_eq!(hex!("a1 b2 c3 d4"), [0xA1, 0xB2, 0xC3, 0xD4]);
}
#[test]
fn test_alphanumeric_upper_space() {
assert_eq!(hex!("E5 E6 90 92"), [0xE5, 0xE6, 0x90, 0x92]);
}
#[test]
fn test_alphanumeric_mixed_space() {
assert_eq!(hex!("0a 0B 0C 0d"), [10, 11, 12, 13]);
}
}