1use digest::Digest;
2use std::io::{self, Read};
3
4pub trait HashFsExt {
5 fn update<R: Read>(&mut self, reader: R) -> io::Result<()>;
6}
7
8impl<D: Digest> HashFsExt for D {
9 fn update<R: Read>(&mut self, mut reader: R) -> io::Result<()> {
10 let mut buffer = [0u8; 64 * 1024]; loop {
12 let bytes_read = reader.read(&mut buffer)?;
13 if bytes_read == 0 {
14 break;
15 }
16 self.update(&buffer[..bytes_read]);
17 }
18 Ok(())
19 }
20}
21
22#[cfg(feature = "io-utils")]
23pub trait HashAsyncFsExt {
24 fn update<R: tokio::io::AsyncRead + Send + Unpin>(
25 &mut self,
26 reader: R,
27 ) -> impl Future<Output = io::Result<()>> + Send;
28}
29
30#[cfg(feature = "io-utils")]
31impl<D: Digest + Send> HashAsyncFsExt for D {
32 async fn update<R: tokio::io::AsyncRead + Send + Unpin>(
33 &mut self,
34 mut reader: R,
35 ) -> io::Result<()> {
36 use tokio::io::AsyncReadExt;
37
38 let mut buffer = [0u8; 64 * 1024]; loop {
40 let bytes_read = reader.read(&mut buffer).await?;
41 if bytes_read == 0 {
42 break;
43 }
44 self.update(&buffer[..bytes_read]);
45 }
46 Ok(())
47 }
48}