#[must_use]
pub fn hex_blake3(bytes: &[u8]) -> String {
hex::encode(blake3::hash(bytes).as_bytes())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hex_blake3_returns_64_char_lowercase_hex() {
let d = hex_blake3(b"hello");
assert_eq!(d.len(), 64, "BLAKE3 digest hex-encodes to 64 chars");
assert!(
d.chars()
.all(|c| c.is_ascii_hexdigit() && !c.is_ascii_uppercase()),
"digest must be lowercase hex: {d}"
);
}
#[test]
fn hex_blake3_is_deterministic() {
assert_eq!(hex_blake3(b"hello"), hex_blake3(b"hello"));
assert_ne!(hex_blake3(b"hello"), hex_blake3(b"world"));
}
#[test]
fn hex_blake3_empty_input_matches_known_digest() {
assert_eq!(
hex_blake3(b""),
"af1349b9f5f9a1a6a0404dea36dcc9499bcb25c9adc112b7cc9a93cae41f3262",
);
}
#[test]
fn hex_blake3_matches_pre_lift_hex_encode_spelling_bytewise() {
for buf in [
b"" as &[u8],
b"x",
b"hello",
&[0u8; 256],
b"tatara-receipt/v1",
b"{\"kind\":\"tatara.export\"}",
] {
assert_eq!(
hex_blake3(buf),
hex::encode(blake3::hash(buf).as_bytes()),
"pre-lift `hex::encode(...)` spelling drifted for buf.len()={}",
buf.len(),
);
}
}
#[test]
fn hex_blake3_matches_pre_lift_to_hex_spelling_bytewise() {
for buf in [
b"" as &[u8],
b"x",
b"hello",
&[0xFFu8; 128],
b"pleme-dev/ephemeral-test-01",
] {
assert_eq!(
hex_blake3(buf),
blake3::hash(buf).to_hex().to_string(),
"pre-lift `.to_hex().to_string()` spelling drifted for buf.len()={}",
buf.len(),
);
}
}
}