#
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}