#[allow(dead_code)] use crate::error::Result;
use std::fs::File;
use std::io::Read;
use std::path::Path;
pub struct Blake3Hasher;
#[allow(dead_code)] impl Blake3Hasher {
pub fn hash_file(path: &Path) -> Result<blake3::Hash> {
let mut file = File::open(path)?;
let mut hasher = blake3::Hasher::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.finalize())
}
pub fn hash_data(data: &[u8]) -> blake3::Hash {
blake3::hash(data)
}
pub fn new_hasher() -> blake3::Hasher {
blake3::Hasher::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
use tempfile::TempDir;
#[test]
fn test_hash_data() {
let data = b"Hello, BLAKE3!";
let hash = Blake3Hasher::hash_data(data);
assert_eq!(hash.as_bytes().len(), 32); }
#[test]
fn test_hash_data_deterministic() {
let data = b"Test data";
let hash1 = Blake3Hasher::hash_data(data);
let hash2 = Blake3Hasher::hash_data(data);
assert_eq!(hash1, hash2);
}
#[test]
fn test_hash_data_different() {
let hash1 = Blake3Hasher::hash_data(b"Data 1");
let hash2 = Blake3Hasher::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 BLAKE3";
fs::write(&file_path, content).unwrap();
let hash = Blake3Hasher::hash_file(&file_path).unwrap();
assert_eq!(hash.as_bytes().len(), 32);
let data_hash = Blake3Hasher::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 = Blake3Hasher::hash_file(&file_path).unwrap();
assert_eq!(hash.as_bytes().len(), 32);
}
#[test]
fn test_incremental_hasher() {
let mut hasher = Blake3Hasher::new_hasher();
hasher.update(b"Hello, ");
hasher.update(b"world!");
let hash1 = hasher.finalize();
let hash2 = Blake3Hasher::hash_data(b"Hello, world!");
assert_eq!(hash1, hash2);
}
#[test]
fn test_empty_data() {
let hash = Blake3Hasher::hash_data(b"");
assert_eq!(hash.as_bytes().len(), 32);
}
#[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 = Blake3Hasher::hash_file(&file_path).unwrap();
let data_hash = Blake3Hasher::hash_data(b"");
assert_eq!(file_hash, data_hash);
}
}