use sha2::{Digest, Sha256};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct WarcDigests {
pub sha256_hex: String,
pub blake3_hex: String,
}
impl WarcDigests {
pub fn to_warc_header(&self) -> String {
format!("sha256:{}", self.sha256_hex)
}
pub fn to_blake3_header(&self) -> String {
format!("blake3:{}", self.blake3_hex)
}
}
pub struct DigestCalculator {
sha256: Sha256,
blake3: blake3::Hasher,
}
impl Default for DigestCalculator {
fn default() -> Self {
Self::new()
}
}
impl DigestCalculator {
pub fn new() -> Self {
Self {
sha256: Sha256::new(),
blake3: blake3::Hasher::new(),
}
}
pub fn update(&mut self, data: &[u8]) {
self.sha256.update(data);
self.blake3.update(data);
}
pub fn finalize(self) -> WarcDigests {
let sha_res = self.sha256.finalize();
let blake_res = self.blake3.finalize();
let mut sha256_hex = String::with_capacity(64);
for b in sha_res {
use std::fmt::Write;
let _ = write!(sha256_hex, "{:02x}", b);
}
WarcDigests {
sha256_hex,
blake3_hex: blake_res.to_hex().to_string(),
}
}
pub fn digest_bytes(data: &[u8]) -> WarcDigests {
let mut calc = Self::new();
calc.update(data);
calc.finalize()
}
}