wasmer_types/
module_hash.rs1use std::fmt::{self, Display, Formatter};
2
3use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
4#[cfg(feature = "enable-serde")]
5use serde::{Deserialize, Serialize};
6use sha2::Digest;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub enum HashAlgorithm {
11 Sha256,
13 XXHash,
15}
16
17#[derive(
19 Debug,
20 Copy,
21 Clone,
22 PartialEq,
23 Eq,
24 Hash,
25 PartialOrd,
26 Ord,
27 RkyvSerialize,
28 RkyvDeserialize,
29 Archive,
30)]
31#[rkyv(derive(Debug))]
32#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
33pub enum ModuleHash {
34 XXHash([u8; 8]),
36
37 Sha256([u8; 32]),
39}
40
41#[cfg(feature = "artifact-size")]
42impl loupe::MemoryUsage for ModuleHash {
43 fn size_of_val(&self, _tracker: &mut dyn loupe::MemoryUsageTracker) -> usize {
44 match self {
45 ModuleHash::XXHash(_) => 8 * 8,
46 ModuleHash::Sha256(_) => 8 * 32,
47 }
48 }
49}
50
51impl ModuleHash {
52 pub fn xxhash_from_bytes(key: [u8; 8]) -> Self {
54 Self::XXHash(key)
55 }
56
57 pub fn sha256_from_bytes(key: [u8; 32]) -> Self {
59 Self::Sha256(key)
60 }
61
62 pub fn xxhash_parse_hex(hex_str: &str) -> Result<Self, hex::FromHexError> {
64 let mut hash = [0_u8; 8];
65 hex::decode_to_slice(hex_str, &mut hash)?;
66 Ok(Self::xxhash_from_bytes(hash))
67 }
68
69 pub fn sha256_parse_hex(hex_str: &str) -> Result<Self, hex::FromHexError> {
71 let mut hash = [0_u8; 32];
72 hex::decode_to_slice(hex_str, &mut hash)?;
73 Ok(Self::sha256_from_bytes(hash))
74 }
75
76 pub fn xxhash(wasm: impl AsRef<[u8]>) -> Self {
78 let wasm = wasm.as_ref();
79
80 let hash = xxhash_rust::xxh64::xxh64(wasm, 0);
81
82 Self::XXHash(hash.to_ne_bytes())
83 }
84
85 pub fn sha256(wasm: impl AsRef<[u8]>) -> Self {
87 let wasm = wasm.as_ref();
88
89 let hash: [u8; 32] = sha2::Sha256::digest(wasm).into();
90
91 Self::Sha256(hash)
92 }
93
94 pub fn random() -> Self {
96 let mut bytes = [0_u8; 8];
97 getrandom::getrandom(&mut bytes).unwrap();
98 Self::XXHash(bytes)
99 }
100
101 pub fn as_bytes(&self) -> &[u8] {
103 match self {
104 Self::XXHash(bytes) => bytes.as_slice(),
105 Self::Sha256(bytes) => bytes.as_slice(),
106 }
107 }
108}
109
110impl Display for ModuleHash {
111 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
112 fn format<const N: usize>(f: &mut Formatter<'_>, bytes: &[u8; N]) -> fmt::Result {
113 for byte in bytes {
114 write!(f, "{byte:02X}")?;
115 }
116
117 Ok(())
118 }
119
120 match self {
121 Self::XXHash(bytes) => format(f, bytes)?,
122 Self::Sha256(bytes) => format(f, bytes)?,
123 }
124
125 Ok(())
126 }
127}