From: Ian Jackson Date: Sat, 1 May 2021 16:45:00 +0000 (+0100) Subject: digest: provide DigestWrite X-Git-Tag: otter-0.6.0~487 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=5b52009084447cd41006dd4e03336d338b05d6c4;p=otter.git digest: provide DigestWrite Signed-off-by: Ian Jackson --- diff --git a/src/utils.rs b/src/utils.rs index 20d079ab..3c2a20d8 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -559,12 +559,51 @@ impl Read for DigestRead { #[test] fn test_digest_read() { let ibuffer = b"abc"; + let exp = Sha512Trunc256::digest(&ibuffer[..]); let inner = &ibuffer[..]; let mut dr = DigestRead::::new(inner); let mut obuffer = [0;4]; assert_eq!( dr.read(&mut obuffer).unwrap(), 3 ); assert_eq!( &obuffer, b"abc\0" ); let got = dr.finish(); + assert_eq!( got, exp ); +} + +#[derive(Debug,Copy,Clone)] +pub struct DigestWrite { + d: D, + w: W, +} + +impl DigestWrite { + pub fn new(w: W) -> Self { DigestWrite { w, d: D::new() } } + pub fn into_inner(self) -> (D, W) { (self.d, self.w) } + pub fn finish(self) -> (digest::Output, W) { + (self.d.finalize(), self.w) + } +} + +impl Write for DigestWrite { + #[throws(io::Error)] + fn write(&mut self, buf: &[u8]) -> usize { + let count = self.w.write(buf)?; + self.d.update(&buf[0..count]); + count + } + #[throws(io::Error)] + fn flush(&mut self) { self.w.flush()? } +} + +#[test] +fn test_digest_write() { + let ibuffer = b"xyz"; let exp = Sha512Trunc256::digest(&ibuffer[..]); + let mut obuffer = [0;4]; + let inner = &mut obuffer[..]; + let mut dw = DigestWrite::::new(inner); + assert_eq!( dw.write(&ibuffer[..]).unwrap(), 3); + let (got, recov) = dw.finish(); + assert_eq!( recov, b"\0" ); assert_eq!( got, exp ); + assert_eq!( &obuffer, b"xyz\0" ); }