1use core::{fmt, ops::Deref};
5
6#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
7#[repr(transparent)]
8pub struct Hash([u8; HASH_LEN]);
9
10impl fmt::Debug for Hash {
11 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12 write!(f, "0x")?;
13 for byte in &self.0 {
14 write!(f, "{byte:02x}")?;
15 }
16 Ok(())
17 }
18}
19
20impl Deref for Hash {
21 type Target = [u8; HASH_LEN];
22
23 fn deref(&self) -> &Self::Target {
24 &self.0
25 }
26}
27
28impl AsRef<[u8]> for Hash {
29 fn as_ref(&self) -> &[u8] {
30 &self.0
31 }
32}
33
34impl AsRef<[u8; HASH_LEN]> for Hash {
35 fn as_ref(&self) -> &[u8; HASH_LEN] {
36 &self.0
37 }
38}
39
40impl From<blake3::Hash> for Hash {
41 fn from(value: blake3::Hash) -> Self {
42 Self(value.into())
43 }
44}
45
46pub const HASH_LEN: usize = 32;
47
48#[derive(Default)]
49pub struct Hasher {
50 inner: blake3::Hasher,
51}
52
53impl Hasher {
54 pub fn hash<T: AsRef<[u8]>>(v: T) -> Hash {
55 use core::hash::Hasher as _;
56 let mut hash = Self::default();
57 hash.write(v.as_ref());
58 hash.finish()
59 }
60
61 pub fn finish(&self) -> Hash {
62 self.inner.finalize().into()
63 }
64}
65
66impl core::hash::Hasher for Hasher {
67 fn write(&mut self, bytes: &[u8]) {
68 self.inner.update(bytes);
69 }
70
71 fn finish(&self) -> u64 {
72 let mut out = [0; 8];
73 let hash = self.inner.finalize();
74 out.copy_from_slice(&hash.as_bytes()[..8]);
75 u64::from_le_bytes(out)
76 }
77}