#[allow(dead_code)] use crate::error::Result;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use xxhash_rust::xxh3::Xxh3;
pub struct XxHash3Hasher;
#[allow(dead_code)] impl XxHash3Hasher {
pub fn hash_file(path: &Path) -> Result<u64> {
let mut file = File::open(path)?;
let mut hasher = Xxh3::new();
let mut buffer = vec![0u8; 1024 * 1024]; loop {
let bytes_read = file.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
hasher.update(&buffer[..bytes_read]);
}
Ok(hasher.digest())
}
pub fn hash_data(data: &[u8]) -> u64 {
xxhash_rust::xxh3::xxh3_64(data)
}
pub fn new_hasher() -> Xxh3 {
Xxh3::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_hash_data() {
let data = b"Hello, xxHash3!";
let hash = XxHash3Hasher::hash_data(data);
assert_ne!(hash, 0); }
#[test]
fn test_hash_data_deterministic() {
let data = b"Test data";
let hash1 = XxHash3Hasher::hash_data(data);
let hash2 = XxHash3Hasher::hash_data(data);
assert_eq!(hash1, hash2);
}
#[test]
fn test_hash_data_different() {
let hash1 = XxHash3Hasher::hash_data(b"Data 1");
let hash2 = XxHash3Hasher::hash_data(b"Data 2");
assert_ne!(hash1, hash2);
}
#[test]
fn test_hash_file() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.txt");
let content = b"File content for xxHash3";
fs::write(&file_path, content).unwrap();
let hash = XxHash3Hasher::hash_file(&file_path).unwrap();
assert_ne!(hash, 0);
let data_hash = XxHash3Hasher::hash_data(content);
assert_eq!(hash, data_hash);
}
#[test]
fn test_hash_large_file() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("large.txt");
let chunk = vec![0x42u8; 1024 * 1024]; let mut file = File::create(&file_path).unwrap();
use std::io::Write;
for _ in 0..10 {
file.write_all(&chunk).unwrap();
}
drop(file);
let hash = XxHash3Hasher::hash_file(&file_path).unwrap();
assert_ne!(hash, 0);
}
#[test]
fn test_incremental_hasher() {
let mut hasher = XxHash3Hasher::new_hasher();
hasher.update(b"Hello, ");
hasher.update(b"world!");
let hash1 = hasher.digest();
let hash2 = XxHash3Hasher::hash_data(b"Hello, world!");
assert_eq!(hash1, hash2);
}
#[test]
fn test_empty_data() {
let hash = XxHash3Hasher::hash_data(b"");
assert_eq!(hash, 0x2d06800538d394c2);
}
#[test]
fn test_empty_file() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("empty.txt");
fs::write(&file_path, b"").unwrap();
let file_hash = XxHash3Hasher::hash_file(&file_path).unwrap();
let data_hash = XxHash3Hasher::hash_data(b"");
assert_eq!(file_hash, data_hash);
}
#[test]
fn test_known_hash() {
let data = b"The quick brown fox jumps over the lazy dog";
let hash = XxHash3Hasher::hash_data(data);
assert_eq!(hash, 0xce7d19a5418fb365);
}
}