1pub trait Hashable {
2 fn update_hasher(&self, hasher: &mut dyn FnMut(&[u8]));
3}
4
5impl Hashable for u8 {
6 fn update_hasher(&self, hasher: &mut dyn FnMut(&[u8])) {
7 hasher(core::slice::from_ref(self))
8 }
9}
10
11impl Hashable for [u8] {
12 fn update_hasher(&self, hasher: &mut dyn FnMut(&[u8])) {
13 hasher(self)
14 }
15}
16
17impl Hashable for str {
18 fn update_hasher(&self, hasher: &mut dyn FnMut(&[u8])) {
19 hasher(str::as_bytes(self))
20 }
21}
22
23impl Hashable for String {
24 fn update_hasher(&self, hasher: &mut dyn FnMut(&[u8])) {
25 hasher(String::as_bytes(self))
26 }
27}
28
29impl<T: Hashable + ?Sized> Hashable for &T {
30 fn update_hasher(&self, hasher: &mut dyn FnMut(&[u8])) {
31 (**self).update_hasher(hasher)
32 }
33}
34
35impl<T: Hashable, const N: usize> Hashable for [T; N] {
36 fn update_hasher(&self, hasher: &mut dyn FnMut(&[u8])) {
37 for item in self {
38 item.update_hasher(hasher);
39 }
40 }
41}
42
43impl<T: Hashable> Hashable for Vec<T> {
44 fn update_hasher(&self, hasher: &mut dyn FnMut(&[u8])) {
45 for item in self {
46 item.update_hasher(hasher);
47 }
48 }
49}
50
51macro_rules! impl_tuple {
52 ($($T:ident),+) => {
53 impl<$($T: Hashable),+> Hashable for ($($T,)+) {
54 fn update_hasher(&self, hasher: &mut dyn FnMut(&[u8])) {
55 #[allow(non_snake_case)]
56 let ($($T,)+) = self;
57 $($T.update_hasher(hasher);)+
58 }
59 }
60 };
61}
62
63impl_tuple!(A);
64impl_tuple!(A, B);
65impl_tuple!(A, B, C);
66impl_tuple!(A, B, C, D);
67impl_tuple!(A, B, C, D, E);
68impl_tuple!(A, B, C, D, E, F);
69impl_tuple!(A, B, C, D, E, F, G);
70impl_tuple!(A, B, C, D, E, F, G, H);