1use crate::functions::{mix_with_p0, read64, wyhash_core, wyhash_finish, wyrng};
2use core::hash::Hasher;
3use rand_core::{impls, Error, RngCore, SeedableRng};
4
5#[derive(Default, Clone)]
7pub struct WyHash {
8 h: u64,
9 size: u64,
10}
11
12impl WyHash {
13 pub fn with_seed(seed: u64) -> Self {
15 WyHash { h: seed, size: 0 }
16 }
17}
18
19impl Hasher for WyHash {
20 #[inline]
21 fn write(&mut self, bytes: &[u8]) {
22 if bytes.is_empty() {
23 self.h = mix_with_p0(self.h);
24 } else {
25 for bytes in bytes.chunks(u64::max_value() as usize) {
26 self.h = wyhash_core(bytes, self.h);
27 self.size += bytes.len() as u64
28 }
29 }
30 }
31 #[inline]
32 fn finish(&self) -> u64 {
33 wyhash_finish(self.size, self.h)
34 }
35}
36
37#[derive(Default, Clone)]
39pub struct WyRng(u64);
40
41impl RngCore for WyRng {
42 fn next_u32(&mut self) -> u32 {
43 self.next_u64() as u32
44 }
45 fn next_u64(&mut self) -> u64 {
46 wyrng(&mut self.0)
47 }
48 fn fill_bytes(&mut self, dest: &mut [u8]) {
49 impls::fill_bytes_via_next(self, dest)
50 }
51 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
52 self.fill_bytes(dest);
53 Ok(())
54 }
55}
56
57impl SeedableRng for WyRng {
58 type Seed = [u8; 8];
59
60 fn from_seed(seed: Self::Seed) -> Self {
61 WyRng(read64(&seed))
62 }
63
64 fn seed_from_u64(state: u64) -> Self {
65 WyRng(state)
66 }
67}