use std::{
fmt::{self, Display, Formatter},
hash::Hash,
};
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
#[cfg(feature = "enable-serde")]
use serde::{Deserialize, Serialize};
use sha2::Digest;
#[derive(
Debug,
Copy,
Clone,
PartialEq,
Eq,
Hash,
PartialOrd,
Ord,
RkyvSerialize,
RkyvDeserialize,
Archive,
)]
#[rkyv(derive(Debug))]
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
pub struct ModuleHash([u8; 32]);
#[cfg(feature = "artifact-size")]
impl loupe::MemoryUsage for ModuleHash {
fn size_of_val(&self, _tracker: &mut dyn loupe::MemoryUsageTracker) -> usize {
size_of::<ModuleHash>()
}
}
impl ModuleHash {
pub fn new(wasm: impl AsRef<[u8]>) -> Self {
let wasm = wasm.as_ref();
let hash = sha2::Sha256::digest(wasm).into();
Self(hash)
}
pub fn sha256(wasm: impl AsRef<[u8]>) -> Self {
Self::new(wasm)
}
pub fn from_bytes(hash: [u8; 32]) -> Self {
Self(hash)
}
pub fn random() -> Self {
let mut bytes = [0_u8; _];
getrandom::fill(&mut bytes).unwrap();
Self(bytes)
}
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
pub fn short_hash(&self) -> String {
hex::encode_upper(&self.as_bytes()[..4])
}
}
impl Display for ModuleHash {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", hex::encode_upper(self.as_bytes()))
}
}