Skip to main content

ps_uuid/helpers/
to_hex.rs

1const LUT: &[u8; 16] = b"0123456789abcdef";
2
3#[must_use]
4pub fn to_hex(bytes: &[u8]) -> String {
5    let mut out = String::with_capacity(bytes.len() * 2);
6
7    for &b in bytes {
8        out.push(LUT[(b >> 4) as usize] as char);
9        out.push(LUT[(b & 0x0f) as usize] as char);
10    }
11
12    out
13}
14
15pub trait ToHex
16where
17    Self: Sized,
18{
19    fn to_hex(self) -> String;
20}
21
22impl<T> ToHex for T
23where
24    T: AsRef<[u8]>,
25{
26    fn to_hex(self) -> String {
27        to_hex(self.as_ref())
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use super::{to_hex, ToHex};
34
35    #[test]
36    fn empty_slice() {
37        let bytes: [u8; 0] = [];
38        assert_eq!(to_hex(&bytes), ""); // Empty input should yield empty string
39    }
40
41    #[test]
42    fn single_byte_zero() {
43        assert_eq!(to_hex(&[0]), "00"); // Zero byte
44    }
45
46    #[test]
47    fn single_byte_max() {
48        assert_eq!(to_hex(&[255]), "ff"); // Maximum byte value
49    }
50
51    #[test]
52    fn single_byte_mid_range() {
53        assert_eq!(to_hex(&[42]), "2a"); // Mid-range byte (42 in decimal is 2A in hex)
54    }
55
56    #[test]
57    fn multiple_bytes() {
58        let bytes = [0x00, 0x01, 0x0A, 0xFF];
59        assert_eq!(to_hex(&bytes), "00010aff"); // Should concatenate hex values
60    }
61
62    #[test]
63    fn all_zeros() {
64        let bytes = [0u8; 10]; // Array of ten zeros
65        assert_eq!(to_hex(&bytes), "00000000000000000000"); // Ten zeros in hex
66    }
67
68    #[test]
69    fn all_ones() {
70        let bytes = [0xFFu8; 5]; // Array of five 0xFF bytes
71        assert_eq!(to_hex(&bytes), "ffffffffff"); // Five 0xFF in hex (10 chars total)
72    }
73
74    #[test]
75    fn mixed_bytes() {
76        let bytes = [0x1A, 0x2B, 0x3C, 0x4D, 0x5E];
77        assert_eq!(to_hex(&bytes), "1a2b3c4d5e"); // Mixed values, all lowercase
78    }
79
80    #[test]
81    fn large_input() {
82        let bytes: Vec<u8> = vec![0xAA; 100]; // 100 bytes of 0xAA
83        let expected: String = "aa".repeat(100); // 100 * "aa" = 200 characters
84        assert_eq!(to_hex(&bytes), expected); // Ensure it handles larger slices
85    }
86
87    #[test]
88    fn ensures_lowercase() {
89        let bytes = [0xAB, 0xCD];
90        assert_eq!(to_hex(&bytes), "abcd"); // Should be lowercase, not "ABCD"
91                                            // Note: The function uses a lookup table for lowercase letters
92    }
93
94    #[test]
95    fn test_trait() {
96        let bytes = b"\xde\xad\xbe\xef";
97        let hex = "deadbeef";
98
99        assert_eq!(hex, bytes.to_hex());
100    }
101}