snix_eval/builtins/
hash.rs

1use bstr::ByteSlice;
2use data_encoding::HEXLOWER;
3use md5::Md5;
4use sha1::Sha1;
5use sha2::{digest::Output, Digest, Sha256, Sha512};
6
7use crate::ErrorKind;
8
9/// Reads through all data from the passed reader, and returns the resulting [Digest].
10/// The exact hash function used is left generic over all [Digest].
11fn hash<D: Digest + std::io::Write>(mut r: impl std::io::Read) -> Result<Output<D>, ErrorKind> {
12    let mut hasher = D::new();
13    std::io::copy(&mut r, &mut hasher)?;
14    Ok(hasher.finalize())
15}
16
17/// For a given algo "string" and reader for data, calculate the digest
18/// and return it as a hexlower encoded [String].
19pub fn hash_nix_string(algo: impl AsRef<[u8]>, s: impl std::io::Read) -> Result<String, ErrorKind> {
20    match algo.as_ref() {
21        b"md5" => Ok(HEXLOWER.encode(hash::<Md5>(s)?.as_bstr())),
22        b"sha1" => Ok(HEXLOWER.encode(hash::<Sha1>(s)?.as_bstr())),
23        b"sha256" => Ok(HEXLOWER.encode(hash::<Sha256>(s)?.as_bstr())),
24        b"sha512" => Ok(HEXLOWER.encode(hash::<Sha512>(s)?.as_bstr())),
25        _ => Err(ErrorKind::UnknownHashType(
26            algo.as_ref().as_bstr().to_string(),
27        )),
28    }
29}