Skip to main content

turbo_tasks_hash/
sha.rs

1use sha2::{Digest, Sha256, Sha384, Sha512, digest::typenum::Unsigned};
2
3use crate::{DeterministicHash, DeterministicHasher};
4
5pub struct ShaHasher<D: Digest>(D);
6
7impl<D: Digest> ShaHasher<D>
8where
9    sha2::digest::Output<D>: core::fmt::LowerHex,
10{
11    /// Uses the DeterministicHash trait to hash the input in a
12    /// cross-platform way.
13    pub fn write_value<T: DeterministicHash>(&mut self, input: T) {
14        input.deterministic_hash(self);
15    }
16
17    /// Uses the DeterministicHash trait to hash the input in a
18    /// cross-platform way.
19    pub fn write_ref<T: DeterministicHash>(&mut self, input: &T) {
20        input.deterministic_hash(self);
21    }
22
23    /// Finish the hash computation and return the digest as hex.
24    pub fn finish(self) -> String {
25        let result = self.0.finalize();
26        format!("{:01$x}", result, D::OutputSize::to_usize() * 2)
27    }
28
29    /// Finish the hash computation and return the digest as base64.
30    pub fn finish_base64(self) -> String {
31        let result = self.0.finalize();
32        data_encoding::BASE64.encode(result.as_slice())
33    }
34}
35
36impl<D: Digest> DeterministicHasher for ShaHasher<D> {
37    fn finish(&self) -> u64 {
38        panic!("use the ShaHasher non-trait function instead");
39    }
40
41    fn write_bytes(&mut self, bytes: &[u8]) {
42        self.0.update(bytes);
43    }
44}
45
46impl ShaHasher<Sha256> {
47    pub fn new_sha256() -> Self {
48        ShaHasher(Sha256::new())
49    }
50}
51impl ShaHasher<Sha384> {
52    pub fn new_sha384() -> Self {
53        ShaHasher(Sha384::new())
54    }
55}
56impl ShaHasher<Sha512> {
57    pub fn new_sha512() -> Self {
58        ShaHasher(Sha512::new())
59    }
60}