#[cfg(not(feature = "sha256"))]
pub(crate) const HASH_ALGORITHM: &str = "blake3";
#[cfg(feature = "sha256")]
pub(crate) const HASH_ALGORITHM: &str = "sha256";
pub(crate) fn hex_encode<const N: usize>(bytes: [u8; N]) -> String {
use std::fmt::Write;
let mut hex = String::with_capacity(N * 2);
for b in bytes {
write!(hex, "{b:02x}").expect("write to String is infallible");
}
hex
}
pub(crate) fn hex_encode_slice(bytes: &[u8]) -> String {
use std::fmt::Write;
let mut hex = String::with_capacity(bytes.len() * 2);
for b in bytes {
write!(hex, "{b:02x}").expect("write to String is infallible");
}
hex
}
pub(crate) fn hex_decode(hex: &str) -> Option<Vec<u8>> {
if !hex.len().is_multiple_of(2) {
return None;
}
(0..hex.len())
.step_by(2)
.map(|i| u8::from_str_radix(&hex[i..i + 2], 16).ok())
.collect()
}
pub(crate) struct ChainHasher {
#[cfg(not(feature = "sha256"))]
inner: blake3::Hasher,
#[cfg(feature = "sha256")]
inner: sha2::Sha256,
}
impl ChainHasher {
#[inline]
pub fn new() -> Self {
Self {
#[cfg(not(feature = "sha256"))]
inner: blake3::Hasher::new(),
#[cfg(feature = "sha256")]
inner: <sha2::Sha256 as sha2::Digest>::new(),
}
}
#[inline]
pub fn update(&mut self, data: &[u8]) {
#[cfg(not(feature = "sha256"))]
{
self.inner.update(data);
}
#[cfg(feature = "sha256")]
{
<sha2::Sha256 as sha2::Digest>::update(&mut self.inner, data);
}
}
#[inline]
pub fn finalize_hex(self) -> String {
#[cfg(not(feature = "sha256"))]
{
self.inner.finalize().to_hex().to_string()
}
#[cfg(feature = "sha256")]
{
format!("{:x}", <sha2::Sha256 as sha2::Digest>::finalize(self.inner))
}
}
}