use crate::String;
use xxhash_rust::xxh3::xxh3_64;
#[inline]
pub fn hash_bytes(data: &[u8]) -> u64 {
xxh3_64(data)
}
#[inline]
pub fn hash_str(data: &str) -> u64 {
xxh3_64(data.as_bytes())
}
#[inline]
pub fn hash_to_hex(hash: u64) -> String {
const HEX: &[u8; 16] = b"0123456789abcdef";
let mut bytes = [0u8; 16];
for (index, byte) in bytes.iter_mut().enumerate() {
let shift = (15 - index) * 4;
*byte = HEX[((hash >> shift) & 0xF) as usize];
}
String::from(unsafe { std::str::from_utf8_unchecked(&bytes) })
}
#[inline]
pub fn content_hash(content: &str) -> String {
hash_to_hex(hash_str(content))
}
#[cfg(test)]
mod tests {
use super::{content_hash, hash_str, hash_to_hex};
#[test]
fn test_hash_consistency() {
let content = "Hello, World!";
let hash1 = hash_str(content);
let hash2 = hash_str(content);
assert_eq!(hash1, hash2);
}
#[test]
fn test_hash_difference() {
let hash1 = hash_str("Hello");
let hash2 = hash_str("World");
assert_ne!(hash1, hash2);
}
#[test]
fn test_hex_format() {
let hash = hash_str("test");
let hex = hash_to_hex(hash);
assert_eq!(hex.len(), 16);
assert!(hex.chars().all(|c| c.is_ascii_hexdigit()));
}
#[test]
fn test_content_hash() {
let hash = content_hash("template content");
assert_eq!(hash.len(), 16);
}
}