simple_hex/
lib.rs

1//! Helper functions to convert between bytes and hex-encoded characters
2#![no_std]
3#![allow(dead_code)]
4
5#[derive(Debug)]
6/// Errors arising from conversion
7pub enum Error {
8    /// Input char not in 0-9, A-F
9    BadChar,
10    /// Output buffer too small to contain results of conversion
11    BufferTooSmall,
12}
13
14/// Convert a nibble to a hex char
15pub fn half_byte_to_hex(i: u8) -> u8 {
16    let h = i & 0xF;
17    if h < 0xA {
18        b'0' + h
19    } else {
20        b'A' + (h - 0xA)
21    }
22}
23
24#[cfg(test)]
25mod test {
26    use super::*;
27
28    #[test]
29    fn half_byte_to_hex_test() {
30        assert_eq!(half_byte_to_hex(0xF), b'F');
31        assert_eq!(half_byte_to_hex(0x0), b'0');
32        assert_eq!(half_byte_to_hex(0x9), b'9');
33        assert_eq!(half_byte_to_hex(0xA), b'A');
34    }
35}
36
37/// Convert a hex character to a nibble
38pub fn hex_to_half_byte(c: u8) -> Result<u8, Error> {
39    if c >= b'0' && c <= b'9' {
40        Ok(c - b'0')
41    } else if c >= b'A' && c <= b'F' {
42        Ok(c - b'A' + 0xA)
43    } else {
44        Err(Error::BadChar)
45    }
46}
47
48/// Convert two hex characters to a byte
49pub fn hex_byte_to_byte(h: u8, l: u8) -> Result<u8, Error> {
50    Ok(hex_to_half_byte(h)? << 4 | hex_to_half_byte(l)? & 0xF)
51}
52
53/// Convert a slice of bytes to a slice of hex characters
54pub fn bytes_to_hex(i: &[u8], o: &mut [u8]) -> Result<(), Error> {
55    if i.len() * 2 > o.len() {
56        return Err(Error::BufferTooSmall);
57    }
58
59    for (i, o) in i.iter().zip(o.chunks_mut(2)) {
60        o[0] = half_byte_to_hex(i >> 4);
61        o[1] = half_byte_to_hex(i & 0xF);
62    }
63    Ok(())
64}
65
66/// Convert a slice of hex characters to bytes
67pub fn hex_to_bytes(i: &[u8], o: &mut [u8]) -> Result<(), Error> {
68    if i.len() / 2 > o.len() {
69        return Err(Error::BufferTooSmall);
70    }
71
72    for (i, o) in i.chunks(2).zip(o.iter_mut()) {
73        *o = hex_byte_to_byte(i[0], i[1])?;
74    }
75
76    Ok(())
77}