Skip to main content

hypershell_hash_components/providers/
stream_checksum.rs

1use core::marker::PhantomData;
2
3use cgp::extra::handler::{Handler, HandlerComponent};
4use cgp::prelude::*;
5use futures::{TryStream, TryStreamExt};
6use sha2::Digest;
7use sha2::digest::generic_array::GenericArray;
8
9use crate::dsl::Checksum;
10
11#[cgp_new_provider]
12impl<Context, Input, Hasher> Handler<Context, Checksum<Hasher>, Input> for HandleStreamChecksum
13where
14    Context: CanRaiseAsyncError<Input::Error>,
15    Input: Send + Unpin + TryStream,
16    Hasher: Send + Digest,
17    Input::Ok: AsRef<[u8]>,
18{
19    type Output = GenericArray<u8, Hasher::OutputSize>;
20
21    async fn handle(
22        _context: &Context,
23        _tag: PhantomData<Checksum<Hasher>>,
24        mut input: Input,
25    ) -> Result<Self::Output, Context::Error> {
26        let mut hasher = Hasher::new();
27
28        while let Some(bytes) = input.try_next().await.map_err(Context::raise_error)? {
29            hasher.update(bytes);
30        }
31
32        Ok(hasher.finalize())
33    }
34}