1use std::convert::Infallible;
6use std::hash::Hasher;
7
8pub trait AlwaysOk<T> {
11 fn aok(self) -> T;
14}
15
16impl<T, I> AlwaysOk<T> for Result<T, I> where I: Into<Infallible> {
17 #[inline] fn aok(self) -> T {
18 match self {
19 Ok(ok) => ok,
20 Err(err) => { let _err: Infallible = err.into(); match _err {} }
21 }
22 }
23}
24
25#[derive(Debug, Copy, Clone, Default)]
27pub struct PassThroughHasher {
28 pub starting_value: u64
30}
31
32impl Hasher for PassThroughHasher {
33 #[inline(always)] fn finish(&self) -> u64 { self.starting_value }
34 #[inline(always)] fn write(&mut self, bytes: &[u8]) {
35 let mut new_value = [0; 8];
36 let mut i = 0;
37 for byte in bytes.iter().rev() {
38 if i >= 8 { break }
39 new_value[7 - i] = *byte;
40 i += 1;
41 }
42 let old_value = self.starting_value.to_ne_bytes();
43 for byte in old_value.iter().rev() {
44 if i >= 8 { break }
45 new_value[7 - i] = *byte;
46 i += 1;
47 }
48 self.starting_value = u64::from_ne_bytes(new_value);
49 }
50 #[inline(always)] fn write_u64(&mut self, value: u64) { self.starting_value = value }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56 use rand_xoshiro::Xoshiro256StarStar;
57 use rand::SeedableRng;
58 use rand::Rng;
59
60 const RNG_SEED: u64 = 0xCAFEDECAF2832;
61
62 #[test]
63 fn pass_through_hasher_works() {
64 let mut hasher = PassThroughHasher::default();
65 assert_eq!(hasher.finish(), 0);
66 hasher.write(&[1, 2, 3, 4]);
67 assert_eq!(hasher.finish(), u64::from_ne_bytes([0, 0, 0, 0, 1, 2, 3, 4]));
68 hasher.write(&[5, 6, 7, 8]);
69 assert_eq!(hasher.finish(), u64::from_ne_bytes([1, 2, 3, 4, 5, 6, 7, 8]));
70
71 let mut rng = Xoshiro256StarStar::seed_from_u64(RNG_SEED);
72 for _ in 0..100 {
73 let val = rng.gen();
74 hasher.write_u64(val);
75 assert_eq!(hasher.finish(), val);
76 hasher.write(&val.to_ne_bytes());
77 assert_eq!(hasher.finish(), val);
78 }
79 }
80}