1
/// Decode a string of hex literals into a vector of bytes.
2
10
pub fn decode_hex(s: &str) -> Result<Vec<u8>, String> {
3
10
    if !s.len().is_multiple_of(2) {
4
2
        Err("Hex string must have an even length".to_string())
5
    } else {
6
8
        (0..s.len())
7
8
            .step_by(2)
8
82
            .map(|i| u8::from_str_radix(&s[i..i + 2], 16).map_err(|e| format!("{e}")))
9
8
            .collect()
10
    }
11
10
}
12

            
13
#[cfg(test)]
14
mod tests {
15
    use super::*;
16

            
17
    #[test]
18
1
    fn test_decode_hex() {
19
1
        assert_eq!(decode_hex("48656c6c6f").unwrap(), b"Hello");
20
1
    }
21

            
22
    #[test]
23
1
    fn test_decode_hex_empty() {
24
1
        assert_eq!(decode_hex("").unwrap(), Vec::<u8>::new());
25
1
    }
26

            
27
    #[test]
28
1
    fn test_decode_hex_odd_length() {
29
1
        let result = decode_hex("48656c6c6");
30
1
        assert!(result.is_err());
31
1
        assert_eq!(result.unwrap_err(), "Hex string must have an even length");
32
1
    }
33

            
34
    #[test]
35
1
    fn test_decode_hex_invalid_char() {
36
1
        let result = decode_hex("48656c6g6f");
37
1
        assert!(result.is_err());
38
1
        assert!(
39
1
            result
40
1
                .unwrap_err()
41
1
                .contains("invalid digit found in string")
42
        );
43
1
    }
44

            
45
    #[test]
46
1
    fn test_decode_hex_uppercase() {
47
1
        assert_eq!(decode_hex("48656C6C6F").unwrap(), b"Hello");
48
1
    }
49

            
50
    #[test]
51
1
    fn test_decode_hex_zero_bytes() {
52
1
        assert_eq!(decode_hex("0000").unwrap(), vec![0, 0]);
53
1
    }
54

            
55
    #[test]
56
1
    fn test_decode_hex_all_ff() {
57
1
        assert_eq!(decode_hex("ffff").unwrap(), vec![255, 255]);
58
1
    }
59
}