use alloc::string::String;
pub fn hex_encode(data: &[u8]) -> String {
::hex::encode(data)
}
pub fn hex_encode_upper(data: &[u8]) -> String {
::hex::encode_upper(data)
}
#[must_use]
pub fn hex_decode(text: &str) -> Option<alloc::vec::Vec<u8>> {
::hex::decode(text).ok()
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::format;
use alloc::vec::Vec;
#[test]
fn encodes_uppercase_zero_padded() {
assert_eq!(hex_encode_upper(&[0xDE, 0xAD, 0xBE, 0xEF]), "DEADBEEF");
assert_eq!(hex_encode_upper(&[]), "");
}
#[test]
fn encodes_lowercase_zero_padded() {
assert_eq!(hex_encode(&[0xDE, 0xAD, 0xBE, 0xEF]), "deadbeef");
assert_eq!(hex_encode(&[0x00, 0x01, 0x0A]), "00010a");
}
#[test]
fn decodes_either_case_and_rejects_odd_or_non_hex() {
assert_eq!(hex_decode("00Ff12"), Some(alloc::vec![0x00, 0xff, 0x12]));
assert_eq!(hex_decode(""), Some(alloc::vec::Vec::new()));
assert_eq!(hex_decode("0"), None);
assert_eq!(hex_decode("zz"), None);
}
#[test]
fn empty_input_is_empty_output() {
assert_eq!(hex_encode(&[]), "");
}
#[test]
fn output_is_always_two_chars_per_byte() {
let all: Vec<u8> = (0..=255u8).collect();
let encoded = hex_encode(&all);
assert_eq!(encoded.len(), all.len() * 2);
let expected: String = all.iter().map(|b| format!("{b:02x}")).collect();
assert_eq!(encoded, expected);
}
}