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 as_bytes(&self) -> &[u8] {
96 match self {
97 Self::XXHash(bytes) => bytes.as_slice(),
98 Self::Sha256(bytes) => bytes.as_slice(),
99 }
100 }
101}
102
103impl Display for ModuleHash {
104 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
105 fn format<const N: usize>(f: &mut Formatter<'_>, bytes: &[u8; N]) -> fmt::Result {
106 for byte in bytes {
107 write!(f, "{byte:02X}")?;
108 }
109
110 Ok(())
111 }
112
113 match self {
114 Self::XXHash(bytes) => format(f, bytes)?,
115 Self::Sha256(bytes) => format(f, bytes)?,
116 }
117
118 Ok(())
119 }
120}