1#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
2pub struct Hash(pub [u8; 32]);
3
4impl From<[u8; 32]> for Hash {
5 fn from(hash: [u8; 32]) -> Self {
6 Self(hash)
7 }
8}
9
10impl core::fmt::Display for Hash {
11 fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
12 for &byte in &self.0 {
13 write!(fmt, "{:02x}", byte)?;
14 }
15
16 Ok(())
17 }
18}
19
20impl core::fmt::Debug for Hash {
21 fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
22 for &byte in &self.0 {
23 write!(fmt, "Hash({:02x})", byte)?;
24 }
25
26 Ok(())
27 }
28}
29
30pub struct Hasher {
31 #[cfg(not(feature = "blake3"))]
32 inner: crate::blake3::Hasher,
33 #[cfg(feature = "blake3")]
34 inner: blake3::Hasher,
35}
36
37impl Default for Hasher {
38 fn default() -> Self {
39 Self::new()
40 }
41}
42
43impl Hasher {
44 pub fn new() -> Self {
45 Self {
46 #[cfg(not(feature = "blake3"))]
47 inner: crate::blake3::Hasher::new(),
48 #[cfg(feature = "blake3")]
49 inner: blake3::Hasher::new(),
50 }
51 }
52
53 pub fn update(&mut self, bytes: &[u8]) {
54 self.inner.update(bytes);
55 }
56
57 pub fn update_u32_array<const N: usize>(&mut self, values: [u32; N]) {
58 if cfg!(target_endian = "little") {
59 let new_length = values.len().checked_mul(4).expect("overflow");
60
61 #[allow(unsafe_code)]
63 let bytes: &[u8] = unsafe { core::slice::from_raw_parts(values.as_ptr().cast::<u8>(), new_length) };
64
65 self.update(bytes)
66 } else {
67 for value in values {
68 self.update(&value.to_le_bytes());
69 }
70 }
71 }
72
73 pub fn finalize(&self) -> Hash {
74 #[cfg(not(feature = "blake3"))]
75 {
76 let mut hash = [0; 32];
77 self.inner.finalize(&mut hash);
78 Hash(hash)
79 }
80 #[cfg(feature = "blake3")]
81 {
82 let h = self.inner.finalize();
83 Hash(*h.as_bytes())
84 }
85 }
86}
87
88impl core::hash::Hasher for Hasher {
89 fn finish(&self) -> u64 {
90 let h = self.finalize().0;
91 u64::from_le_bytes([h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]])
92 }
93
94 fn write(&mut self, bytes: &[u8]) {
95 self.update(bytes);
96 }
97}