snops_common/
util.rs

1use std::{fmt::Debug, io::Read, path::PathBuf};
2
3use sha2::{Digest, Sha256};
4
5/// A wrapper struct that has an "opaque" `Debug` implementation for types
6/// that do not implement `Debug`.
7pub struct OpaqueDebug<T>(pub T);
8
9impl<T: Default> Default for OpaqueDebug<T> {
10    fn default() -> Self {
11        Self(T::default())
12    }
13}
14
15impl<T> Debug for OpaqueDebug<T> {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        f.write_str("(...)")
18    }
19}
20
21impl<T> std::ops::Deref for OpaqueDebug<T> {
22    type Target = T;
23
24    fn deref(&self) -> &Self::Target {
25        &self.0
26    }
27}
28
29impl<T> std::ops::DerefMut for OpaqueDebug<T> {
30    fn deref_mut(&mut self) -> &mut Self::Target {
31        &mut self.0
32    }
33}
34
35/// Calculate the SHA-256 hash of a file.
36pub fn sha256_file(path: &PathBuf) -> Result<String, std::io::Error> {
37    let mut digest = Sha256::new();
38    let mut file = std::fs::File::open(path)?;
39    let mut buffer = [0; 1024];
40    loop {
41        let n = file.read(&mut buffer)?;
42        if n == 0 {
43            break;
44        }
45        digest.update(&buffer[..n]);
46    }
47
48    Ok(format!("{:x}", digest.finalize()))
49}