use std::io::{self, Read}; use blake2b_simd::State; /// Abstraction over a reader which hashes the data being read. pub struct HashReader { reader: R, hasher: State, } impl HashReader { /// Construct a new `HashReader` given an existing `reader` by value. pub fn new(reader: R) -> Self { HashReader { reader, hasher: State::new(), } } /// Destroy this reader and return the hash of what was read. pub fn into_hash(self) -> String { let hash = self.hasher.finalize(); let mut s = String::new(); for c in hash.as_bytes().iter() { s += &format!("{:02x}", c); } s } } impl Read for HashReader { fn read(&mut self, buf: &mut [u8]) -> io::Result { let bytes = self.reader.read(buf)?; if bytes > 0 { self.hasher.update(&buf[0..bytes]); } Ok(bytes) } }