#[cfg(test)]
mod tests;
use super::{ArtifactIdentity, BoundedWriter, Sha256Digest};
use sha2::{Digest, Sha256};
use std::io::{self, Write};
pub struct HashingWriter<W> {
writer: BoundedWriter<W>,
hasher: Sha256,
}
impl<W> HashingWriter<W> {
#[must_use]
pub fn new(writer: W, max_bytes: u64) -> Self {
Self {
writer: BoundedWriter::new(writer, max_bytes),
hasher: Sha256::new(),
}
}
#[must_use]
pub const fn bytes_written(&self) -> u64 {
self.writer.bytes_written()
}
#[must_use]
pub const fn limit_exceeded(&self) -> bool {
self.writer.limit_exceeded()
}
#[must_use]
pub fn into_parts(self) -> (W, ArtifactIdentity) {
let identity = ArtifactIdentity {
bytes: self.writer.bytes_written(),
sha256: Sha256Digest::from_bytes(self.hasher.finalize().into()),
};
(self.writer.into_inner(), identity)
}
}
impl<W: Write> Write for HashingWriter<W> {
fn write(&mut self, buffer: &[u8]) -> io::Result<usize> {
let accepted = self.writer.write(buffer)?;
self.hasher.update(&buffer[..accepted]);
Ok(accepted)
}
fn flush(&mut self) -> io::Result<()> {
self.writer.flush()
}
}