use std::io::Read; use std::path::Path; use nix_nar::Encoder; use sha2::{Digest, Sha256}; use fix_error::{Error, Result}; pub fn compute_nar_hash(path: &Path) -> Result<[u8; 32]> { let mut hasher = Sha256::new(); std::io::copy( &mut Encoder::new(path).map_err(|err| Error::internal(err.to_string()))?, &mut hasher, ) .map_err(|err| Error::internal(err.to_string()))?; Ok(hasher.finalize().into()) } pub fn pack_nar(path: &Path) -> Result> { let mut buffer = Vec::new(); Encoder::new(path) .map_err(|err| Error::internal(err.to_string()))? .read_to_end(&mut buffer) .map_err(|err| Error::internal(err.to_string()))?; Ok(buffer) } #[cfg(test)] #[allow(clippy::unwrap_used)] mod tests { use std::fs; use tempfile::TempDir; use super::*; #[test_log::test] fn test_simple_file() { let temp = TempDir::new().unwrap(); let file_path = temp.path().join("test.txt"); fs::write(&file_path, "hello").unwrap(); let hash = hex::encode(compute_nar_hash(&file_path).unwrap()); assert_eq!( hash, "0a430879c266f8b57f4092a0f935cf3facd48bbccde5760d4748ca405171e969" ); assert!(!hash.is_empty()); assert_eq!(hash.len(), 64); } #[test_log::test] fn test_directory() { let temp = TempDir::new().unwrap(); fs::write(temp.path().join("a.txt"), "aaa").unwrap(); fs::write(temp.path().join("b.txt"), "bbb").unwrap(); let hash = hex::encode(compute_nar_hash(temp.path()).unwrap()); assert_eq!( hash, "0036c14209749bc9b9631e2077b108b701c322ab53853cd26f2746268a86fc0f" ); assert!(!hash.is_empty()); assert_eq!(hash.len(), 64); } }