summaryrefslogtreecommitdiffstats
path: root/crates/cargo-util/src/sha256.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/cargo-util/src/sha256.rs')
-rw-r--r--crates/cargo-util/src/sha256.rs56
1 files changed, 56 insertions, 0 deletions
diff --git a/crates/cargo-util/src/sha256.rs b/crates/cargo-util/src/sha256.rs
new file mode 100644
index 0000000..58821f4
--- /dev/null
+++ b/crates/cargo-util/src/sha256.rs
@@ -0,0 +1,56 @@
+use super::paths;
+use anyhow::{Context, Result};
+use crypto_hash::{Algorithm, Hasher};
+use std::fs::File;
+use std::io::{self, Read, Write};
+use std::path::Path;
+
+pub struct Sha256(Hasher);
+
+impl Sha256 {
+ pub fn new() -> Sha256 {
+ let hasher = Hasher::new(Algorithm::SHA256);
+ Sha256(hasher)
+ }
+
+ pub fn update(&mut self, bytes: &[u8]) -> &mut Sha256 {
+ let _ = self.0.write_all(bytes);
+ self
+ }
+
+ pub fn update_file(&mut self, mut file: &File) -> io::Result<&mut Sha256> {
+ let mut buf = [0; 64 * 1024];
+ loop {
+ let n = file.read(&mut buf)?;
+ if n == 0 {
+ break Ok(self);
+ }
+ self.update(&buf[..n]);
+ }
+ }
+
+ pub fn update_path<P: AsRef<Path>>(&mut self, path: P) -> Result<&mut Sha256> {
+ let path = path.as_ref();
+ let file = paths::open(path)?;
+ self.update_file(&file)
+ .with_context(|| format!("failed to read `{}`", path.display()))?;
+ Ok(self)
+ }
+
+ pub fn finish(&mut self) -> [u8; 32] {
+ let mut ret = [0u8; 32];
+ let data = self.0.finish();
+ ret.copy_from_slice(&data[..]);
+ ret
+ }
+
+ pub fn finish_hex(&mut self) -> String {
+ hex::encode(self.finish())
+ }
+}
+
+impl Default for Sha256 {
+ fn default() -> Self {
+ Self::new()
+ }
+}