1 #![doc = include_str!("../README.md")]
4 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
5 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
8 const fn next_hex_char(string: &[u8], mut pos: usize) -> Option<(u8, usize)> {
9 while pos < string.len() {
10 let raw_val = string[pos];
12 let val = match raw_val {
13 b'0'..=b'9' => raw_val - 48,
14 b'A'..=b'F' => raw_val - 55,
15 b'a'..=b'f' => raw_val - 87,
16 b' ' | b'\r' | b'\n' | b'\t' => continue,
17 0..=127 => panic!("Encountered invalid ASCII character"),
18 _ => panic!("Encountered non-ASCII character"),
20 return Some((val, pos));
25 const fn next_byte(string: &[u8], pos: usize) -> Option<(u8, usize)> {
26 let (half1, pos) = match next_hex_char(string, pos) {
30 let (half2, pos) = match next_hex_char(string, pos) {
32 None => panic!("Odd number of hex characters"),
34 Some(((half1 << 4) + half2, pos))
37 /// Compute length of a byte array which will be decoded from the strings.
39 /// This function is an implementation detail and SHOULD NOT be called directly!
41 pub const fn len(strings: &[&[u8]]) -> usize {
44 while i < strings.len() {
46 while let Some((_, new_pos)) = next_byte(strings[i], pos) {
55 /// Decode hex strings into a byte array of pre-computed length.
57 /// This function is an implementation detail and SHOULD NOT be called directly!
59 pub const fn decode<const LEN: usize>(strings: &[&[u8]]) -> [u8; LEN] {
61 let mut buf = [0u8; LEN];
63 while i < strings.len() {
65 while let Some((byte, new_pos)) = next_byte(strings[i], pos) {
73 panic!("Length mismatch. Please report this bug.");
78 /// Macro for converting sequence of string literals containing hex-encoded data
79 /// into an array of bytes.
82 ($($s:literal)*) => {{
83 const STRINGS: &[&'static [u8]] = &[$($s.as_bytes(),)*];
84 const LEN: usize = $crate::len(STRINGS);
85 const RES: [u8; LEN] = $crate::decode(STRINGS);