cargo_util/
sha256.rs

1use super::paths;
2use anyhow::{Context, Result};
3use sha2::{Digest, Sha256 as Sha2_sha256};
4use std::fs::File;
5use std::io::{self, Read};
6use std::path::Path;
7
8pub struct Sha256(Sha2_sha256);
9
10impl Sha256 {
11    pub fn new() -> Sha256 {
12        let hasher = Sha2_sha256::new();
13        Sha256(hasher)
14    }
15
16    pub fn update(&mut self, bytes: &[u8]) -> &mut Sha256 {
17        let _ = self.0.update(bytes);
18        self
19    }
20
21    pub fn update_file(&mut self, mut file: &File) -> io::Result<&mut Sha256> {
22        let mut buf = [0; 64 * 1024];
23        loop {
24            let n = file.read(&mut buf)?;
25            if n == 0 {
26                break Ok(self);
27            }
28            self.update(&buf[..n]);
29        }
30    }
31
32    pub fn update_path<P: AsRef<Path>>(&mut self, path: P) -> Result<&mut Sha256> {
33        let path = path.as_ref();
34        let file = paths::open(path)?;
35        self.update_file(&file)
36            .with_context(|| format!("failed to read `{}`", path.display()))?;
37        Ok(self)
38    }
39
40    pub fn finish(&mut self) -> [u8; 32] {
41        self.0.finalize_reset().into()
42    }
43
44    pub fn finish_hex(&mut self) -> String {
45        hex::encode(self.finish())
46    }
47}
48
49impl Default for Sha256 {
50    fn default() -> Self {
51        Self::new()
52    }
53}