Skip to main content

rushdb_query/
hex.rs

1//! Record-id hex decoding.
2
3/// Decode exactly 16 bytes from a 32-character hex string (case-insensitive).
4///
5/// Returns `None` when the input is shorter than 32 characters or contains a
6/// non-hex digit.
7#[must_use]
8pub fn hex_decode_16(hex: &str) -> Option<[u8; 16]> {
9    let mut out = [0u8; 16];
10    for (i, byte) in out.iter_mut().enumerate() {
11        let hi = hex.as_bytes().get(i * 2)?.hex_val()?;
12        let lo = hex.as_bytes().get(i * 2 + 1)?.hex_val()?;
13        *byte = (hi << 4) | lo;
14    }
15    Some(out)
16}
17
18trait HexVal {
19    fn hex_val(self) -> Option<u8>;
20}
21
22impl HexVal for u8 {
23    fn hex_val(self) -> Option<u8> {
24        match self {
25            b'0'..=b'9' => Some(self - b'0'),
26            b'a'..=b'f' => Some(self - b'a' + 10),
27            b'A'..=b'F' => Some(self - b'A' + 10),
28            _ => None,
29        }
30    }
31}