1use serde::{Deserialize, Serialize};
4use std::{collections::BTreeMap, marker::PhantomData};
5
6#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Serialize, Deserialize)]
9#[serde(transparent)]
10pub struct Hash<K: HashKind>([u8; 32], #[serde(skip)] PhantomData<K>);
11
12impl<K: HashKind> std::fmt::Debug for Hash<K> {
13 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14 write!(f, "{:x?}", self.0)
15 }
16}
17
18pub trait HashKind {}
19
20pub struct Hasher<K: HashKind>(blake3::Hasher, PhantomData<K>);
21
22impl<K: HashKind> Default for Hasher<K> {
23 fn default() -> Self {
24 Self::new()
25 }
26}
27
28impl<K: HashKind> Hasher<K> {
29 pub fn new() -> Self {
30 Self(blake3::Hasher::new(), PhantomData)
31 }
32 pub fn update(&mut self, input: &[u8]) -> &mut Self {
33 self.0.update(input);
34 self
35 }
36 pub fn finalize(&self) -> Hash<K> {
37 Hash(self.0.finalize().into(), PhantomData)
38 }
39}
40
41impl<K: HashKind> std::io::Write for Hasher<K> {
43 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
44 self.0.update(buf);
45 Ok(buf.len())
46 }
47 fn flush(&mut self) -> std::io::Result<()> {
48 Ok(())
49 }
50}
51
52pub type HashedMap<K, T> = BTreeMap<Hash<K>, T>;
53
54#[derive(Copy, Clone, PartialEq, Eq, Default)]
55pub struct AssetKind;
56
57impl HashKind for AssetKind {}
58
59pub type AssetHash = Hash<AssetKind>;
60
61#[derive(Copy, Clone, PartialEq, Eq, Default)]
62pub struct DocKind;
63
64impl HashKind for DocKind {}
65
66pub type DocHash = Hash<DocKind>;