1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//! Small lowercase-hex codec with no dependencies.
//!
//! It sits outside [`crate::crypto`] so callers that do not build
//! `hmac` and `sha2`, such as pagination cursors and `row_to_json`,
//! can share the same code. `crate::crypto` re-exports it.
/// Render `bytes` as a lowercase hex string (no separator).
#[must_use]
pub(crate) fn hex_encode(bytes: &[u8]) -> String {
const HEX: &[u8; 16] = b"0123456789abcdef";
let mut out = String::with_capacity(bytes.len() * 2);
for b in bytes {
out.push(HEX[(b >> 4) as usize] as char);
out.push(HEX[(b & 0xf) as usize] as char);
}
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_yields_empty() {
assert_eq!(hex_encode(&[]), "");
}
#[test]
fn known_byte_vector() {
assert_eq!(hex_encode(&[0xde, 0xad, 0xbe, 0xef]), "deadbeef");
}
#[test]
fn full_byte_range_is_lowercase() {
let all: Vec<u8> = (0..=255u8).collect();
let s = hex_encode(&all);
assert_eq!(s.len(), 512);
assert!(s.chars().all(|c| c.is_ascii_hexdigit()));
assert!(!s.chars().any(|c| c.is_ascii_uppercase()));
}
}