1use std::fmt;
9
10#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
11pub struct ContentHash(pub [u8; 32]);
12
13impl ContentHash {
14 pub const ZERO: Self = Self([0; 32]);
15
16 pub fn from_bytes(bytes: [u8; 32]) -> Self {
17 Self(bytes)
18 }
19
20 pub fn short_hex(&self) -> String {
21 let mut s = String::with_capacity(16);
22 for b in &self.0[..8] {
23 s.push_str(&format!("{:02x}", b));
24 }
25 s
26 }
27
28 pub fn full_hex(&self) -> String {
29 let mut s = String::with_capacity(64);
30 for b in &self.0 {
31 s.push_str(&format!("{:02x}", b));
32 }
33 s
34 }
35}
36
37impl fmt::Debug for ContentHash {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 write!(f, "ContentHash({})", self.short_hex())
40 }
41}
42
43impl fmt::Display for ContentHash {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 f.write_str(&self.short_hex())
46 }
47}
48
49#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
50pub struct ParamHash(pub [u8; 32]);
51
52impl ParamHash {
53 pub fn from_bytes(bytes: [u8; 32]) -> Self {
54 Self(bytes)
55 }
56
57 pub fn short_hex(&self) -> String {
58 let mut s = String::with_capacity(16);
59 for b in &self.0[..8] {
60 s.push_str(&format!("{:02x}", b));
61 }
62 s
63 }
64}
65
66impl fmt::Debug for ParamHash {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 write!(f, "ParamHash({})", self.short_hex())
69 }
70}
71
72pub struct ParamHasher(blake3::Hasher);
78
79impl Default for ParamHasher {
80 fn default() -> Self {
81 Self(blake3::Hasher::new())
82 }
83}
84
85impl ParamHasher {
86 pub fn new() -> Self {
87 Self::default()
88 }
89
90 pub fn finalize(self) -> ParamHash {
91 ParamHash(*self.0.finalize().as_bytes())
92 }
93}
94
95impl std::hash::Hasher for ParamHasher {
96 fn write(&mut self, bytes: &[u8]) {
97 self.0.update(bytes);
98 }
99
100 fn finish(&self) -> u64 {
101 let h = self.0.finalize();
102 let mut buf = [0u8; 8];
103 buf.copy_from_slice(&h.as_bytes()[..8]);
104 u64::from_le_bytes(buf)
105 }
106}