Skip to main content

nix_compat/nixhash/
io.rs

1//! Helpers that calcutate the hash of the data written
2//! and count the number of bytes written.
3
4use std::io;
5
6use tokio::io::{AsyncBufRead, AsyncRead, AsyncWrite, copy, copy_buf};
7use tokio_util::io::InspectWriter;
8
9use super::{HashAlgo, NixHash, NixHashDigester, Sha256, Sha256Digester};
10
11/// Asynchronously copies the entire contents of a reader into a writer while hashing.
12pub async fn copy_hashed<'a, R, W>(
13    reader: &'a mut R,
14    writer: &'a mut W,
15    algo: HashAlgo,
16) -> io::Result<(u64, NixHash)>
17where
18    R: AsyncRead + Unpin + ?Sized,
19    W: AsyncWrite + Unpin + ?Sized,
20{
21    let mut digester = NixHashDigester::new(algo);
22    let mut writer = InspectWriter::new(writer, |data| {
23        digester.update(data);
24    });
25    let written = copy(reader, &mut writer).await?;
26    let hash = digester.finalize();
27    Ok((written, hash))
28}
29
30/// Asynchronously copies the entire contents of a reader into a writer while hashing.
31pub async fn copy_buf_hashed<'a, R, W>(
32    reader: &'a mut R,
33    writer: &'a mut W,
34    algo: HashAlgo,
35) -> io::Result<(u64, NixHash)>
36where
37    R: AsyncBufRead + Unpin + ?Sized,
38    W: AsyncWrite + Unpin + ?Sized,
39{
40    let mut digester = NixHashDigester::new(algo);
41    let mut writer = InspectWriter::new(writer, |data| {
42        digester.update(data);
43    });
44    let written = copy_buf(reader, &mut writer).await?;
45    let hash = digester.finalize();
46    Ok((written, hash))
47}
48
49/// Asynchronously copies the entire contents of a reader into a writer while hashing.
50pub async fn copy_sha256<'a, R, W>(
51    reader: &'a mut R,
52    writer: &'a mut W,
53) -> io::Result<(u64, Sha256)>
54where
55    R: AsyncRead + Unpin + ?Sized,
56    W: AsyncWrite + Unpin + ?Sized,
57{
58    let mut digester = Sha256Digester::new();
59    let mut writer = InspectWriter::new(writer, |data| {
60        digester.update(data);
61    });
62    let written = copy(reader, &mut writer).await?;
63    let hash = digester.finalize();
64    Ok((written, hash))
65}
66
67/// Asynchronously copies the entire contents of a reader into a writer while hashing.
68pub async fn copy_buf_sha256<'a, R, W>(
69    reader: &'a mut R,
70    writer: &'a mut W,
71) -> io::Result<(u64, Sha256)>
72where
73    R: AsyncBufRead + Unpin + ?Sized,
74    W: AsyncWrite + Unpin + ?Sized,
75{
76    let mut digester = Sha256Digester::new();
77    let mut writer = InspectWriter::new(writer, |data| {
78        digester.update(data);
79    });
80    let written = copy_buf(reader, &mut writer).await?;
81    let hash = digester.finalize();
82    Ok((written, hash))
83}