1use crate::{Result, RwBuilder};
2use digest::Digest;
3use std::io::{Read, Write};
4
5#[derive(Debug)]
7#[must_use]
8pub struct DigestBuilder<B, D>
9where
10 B: RwBuilder,
11 D: Digest,
12{
13 builder: B,
15 _marker: std::marker::PhantomData<D>,
17}
18
19impl<B, D> DigestBuilder<B, D>
20where
21 B: RwBuilder,
22 D: Digest,
23{
24 pub const fn new(builder: B) -> Self {
26 Self { builder, _marker: std::marker::PhantomData }
27 }
28}
29
30#[cfg(feature = "sha2")]
32pub type Sha256Builder<B> = DigestBuilder<B, ::sha2::Sha256>;
33#[cfg(feature = "sha2")]
35pub type Sha512Builder<B> = DigestBuilder<B, ::sha2::Sha512>;
36
37#[cfg(feature = "sha3")]
39pub type Sha3_256Builder<B> = DigestBuilder<B, ::sha3::Sha3_256>;
40#[cfg(feature = "sha3")]
42pub type Sha3_512Builder<B> = DigestBuilder<B, ::sha3::Sha3_512>;
43
44impl<B, D> RwBuilder for DigestBuilder<B, D>
45where
46 B: RwBuilder,
47 B::Reader: Read,
48 B::Writer: Write,
49 D: Digest,
50{
51 type Reader = DigestReader<B::Reader, D>;
52 type Writer = DigestWriter<B::Writer, D>;
53
54 fn reader(&self) -> Result<Self::Reader> {
55 Ok(DigestReader::new(self.builder.reader()?))
56 }
57
58 fn writer(&self) -> Result<Self::Writer> {
59 Ok(DigestWriter::new(self.builder.writer()?))
60 }
61}
62
63#[derive(Debug)]
65pub struct DigestReader<R, D>
66where
67 R: Read,
68 D: Digest,
69{
70 inner: R,
72 hasher: D,
74}
75
76impl<R, D> DigestReader<R, D>
77where
78 R: Read,
79 D: Digest,
80{
81 pub fn new(inner: R) -> Self {
83 Self { inner, hasher: D::new() }
84 }
85
86 pub fn finalize(self) -> digest::Output<D> {
88 self.hasher.finalize()
89 }
90
91 pub fn into_inner(self) -> R {
93 self.inner
94 }
95}
96
97impl<R, D> Read for DigestReader<R, D>
98where
99 R: Read,
100 D: Digest,
101{
102 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
103 let n = self.inner.read(buf)?;
104 self.hasher.update(&buf[..n]);
105 Ok(n)
106 }
107}
108
109#[derive(Debug)]
111pub struct DigestWriter<W, D>
112where
113 W: Write,
114 D: Digest,
115{
116 inner: W,
118 hasher: D,
120}
121
122impl<W, D> DigestWriter<W, D>
123where
124 W: Write,
125 D: Digest,
126{
127 pub fn new(inner: W) -> Self {
129 Self { inner, hasher: D::new() }
130 }
131
132 pub fn finalize(self) -> digest::Output<D> {
134 self.hasher.finalize()
135 }
136
137 pub fn into_inner(self) -> W {
139 self.inner
140 }
141}
142
143impl<W, D> Write for DigestWriter<W, D>
144where
145 W: Write,
146 D: Digest,
147{
148 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
149 let n = self.inner.write(buf)?;
150 self.hasher.update(&buf[..n]);
151 Ok(n)
152 }
153
154 fn flush(&mut self) -> std::io::Result<()> {
155 self.inner.flush()
156 }
157}