use std::path::Path;
#[cfg(feature = "operations")]
use std::path::PathBuf;
use crate::error::{classify_io_error, Result};
pub(crate) fn hash_file(path: &Path) -> Result<[u8; 32]> {
let mut hasher = blake3::Hasher::new();
let mut file =
std::fs::File::open(path).map_err(|e| classify_io_error(e, path.to_path_buf(), 0))?;
std::io::copy(&mut file, &mut hasher)
.map_err(|e| classify_io_error(e, path.to_path_buf(), 0))?;
Ok(*hasher.finalize().as_bytes())
}
#[cfg(feature = "operations")]
async fn hash_file_async(path: PathBuf) -> Result<[u8; 32]> {
tokio::task::spawn_blocking(move || hash_file(&path))
.await
.expect("hash task panicked")
}
#[cfg(feature = "operations")]
pub(crate) async fn files_identical(a: &Path, b: &Path, a_size: u64, b_size: u64) -> Result<bool> {
if a_size != b_size {
return Ok(false);
}
let (hash_a, hash_b) = tokio::try_join!(
hash_file_async(a.to_path_buf()),
hash_file_async(b.to_path_buf())
)?;
Ok(hash_a == hash_b)
}