use std::fs::File;
use std::io::{BufReader, Read};
use std::path::Path;
use sha2::{Digest, Sha256};
use super::error::PackageError;
pub(crate) fn file_sha256(path: &Path) -> Result<String, PackageError> {
let file = File::open(path).map_err(|source| PackageError::Read {
path: path.to_path_buf(),
source,
})?;
let mut reader = BufReader::new(file);
let mut hasher = Sha256::new();
let mut buffer = [0u8; 64 * 1024];
loop {
let n = reader
.read(&mut buffer)
.map_err(|source| PackageError::Read {
path: path.to_path_buf(),
source,
})?;
if n == 0 {
break;
}
hasher.update(&buffer[..n]);
}
let digest = hasher.finalize();
Ok(format!("{:x}", digest))
}
pub(crate) fn write_checksums(path: &Path, content: &str) -> Result<(), PackageError> {
std::fs::write(path, content).map_err(|source| PackageError::Write {
path: path.to_path_buf(),
source,
})
}
#[cfg(test)]
mod tests {
use super::file_sha256;
use std::fs;
#[test]
fn file_sha256_matches_known_value() {
let dir = tempfile::tempdir().expect("tempdir");
let path = dir.path().join("abc.txt");
fs::write(&path, b"abc").expect("write");
let digest = file_sha256(&path).expect("digest");
assert_eq!(
digest,
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
);
}
#[test]
fn empty_file_has_known_digest() {
let dir = tempfile::tempdir().expect("tempdir");
let path = dir.path().join("empty");
fs::write(&path, b"").expect("write");
let digest = file_sha256(&path).expect("digest");
assert_eq!(
digest,
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
);
}
}