wasmer_types/
module_hash.rs

1use std::{
2    fmt::{self, Display, Formatter},
3    hash::Hash,
4};
5
6use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
7#[cfg(feature = "enable-serde")]
8use serde::{Deserialize, Serialize};
9use sha2::Digest;
10
11/// The hash of a WebAssembly module.
12#[derive(
13    Debug,
14    Copy,
15    Clone,
16    PartialEq,
17    Eq,
18    Hash,
19    PartialOrd,
20    Ord,
21    RkyvSerialize,
22    RkyvDeserialize,
23    Archive,
24)]
25#[rkyv(derive(Debug))]
26#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
27pub enum ModuleHash {
28    /// Deprecated.
29    XXHash([u8; 8]),
30
31    /// sha256
32    Sha256([u8; 32]),
33}
34
35#[cfg(feature = "artifact-size")]
36impl loupe::MemoryUsage for ModuleHash {
37    fn size_of_val(&self, _tracker: &mut dyn loupe::MemoryUsageTracker) -> usize {
38        match self {
39            Self::XXHash(_) => 8 * 8,
40            Self::Sha256(_) => 8 * 32,
41        }
42    }
43}
44
45impl ModuleHash {
46    /// Generate a new [`ModuleHash`] based on the Sha256 hash of some bytes.
47    pub fn new(wasm: impl AsRef<[u8]>) -> Self {
48        let wasm = wasm.as_ref();
49        let hash = sha2::Sha256::digest(wasm).into();
50        Self::Sha256(hash)
51    }
52
53    /// Generate a new [`ModuleHash`] based on the Sha256 hash of some bytes.
54    pub fn sha256(wasm: impl AsRef<[u8]>) -> Self {
55        let wasm = wasm.as_ref();
56
57        let hash: [u8; 32] = sha2::Sha256::digest(wasm).into();
58
59        Self::Sha256(hash)
60    }
61
62    /// Create a new [`ModuleHash`] from the raw sha256 hash.
63    pub fn from_bytes(hash: [u8; 32]) -> Self {
64        Self::Sha256(hash)
65    }
66
67    /// Generate a random [`ModuleHash`]. For when you don't care about caches.
68    pub fn random() -> Self {
69        let mut bytes = [0_u8; _];
70        getrandom::getrandom(&mut bytes).unwrap();
71        Self::Sha256(bytes)
72    }
73
74    /// Get the raw hash.
75    pub fn as_bytes(&self) -> &[u8] {
76        match self {
77            Self::XXHash(bytes) => bytes.as_slice(),
78            Self::Sha256(bytes) => bytes.as_slice(),
79        }
80    }
81
82    /// Build a short hex representation of the hash (first 4 bytes).
83    pub fn short_hash(&self) -> String {
84        hex::encode_upper(&self.as_bytes()[..4])
85    }
86}
87
88impl Display for ModuleHash {
89    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
90        write!(f, "{}", hex::encode_upper(self.as_bytes()))
91    }
92}