use core::fmt;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CodecProfileDigest([u8; 32]);
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ArtifactDigest([u8; 32]);
impl CodecProfileDigest {
pub fn from_canonical_bytes(bytes: &[u8]) -> Self {
Self(*blake3::hash(bytes).as_bytes())
}
pub fn from_parts(parts: &[&[u8]]) -> Self {
let mut hasher = blake3::Hasher::new();
for part in parts {
hasher.update(&(part.len() as u64).to_le_bytes());
hasher.update(part);
}
Self(*hasher.finalize().as_bytes())
}
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
pub fn to_hex(self) -> String {
hex32(&self.0)
}
}
impl ArtifactDigest {
pub fn from_canonical_bytes(bytes: &[u8]) -> Self {
Self(*blake3::hash(bytes).as_bytes())
}
pub fn from_parts(parts: &[&[u8]]) -> Self {
let mut hasher = blake3::Hasher::new();
for part in parts {
hasher.update(&(part.len() as u64).to_le_bytes());
hasher.update(part);
}
Self(*hasher.finalize().as_bytes())
}
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
pub fn to_hex(self) -> String {
hex32(&self.0)
}
}
impl fmt::Debug for CodecProfileDigest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("CodecProfileDigest")
.field(&self.to_hex())
.finish()
}
}
impl fmt::Display for CodecProfileDigest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.to_hex())
}
}
impl fmt::Debug for ArtifactDigest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("ArtifactDigest")
.field(&self.to_hex())
.finish()
}
}
impl fmt::Display for ArtifactDigest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.to_hex())
}
}
fn hex32(bytes: &[u8; 32]) -> String {
const HEX: &[u8; 16] = b"0123456789abcdef";
let mut out = [0u8; 64];
for (idx, byte) in bytes.iter().enumerate() {
out[idx * 2] = HEX[(byte >> 4) as usize];
out[idx * 2 + 1] = HEX[(byte & 0x0f) as usize];
}
String::from_utf8(out.to_vec()).expect("hex table is valid utf8")
}