use core::hash::{BuildHasher};
use crate::inner::RapidHasher;
use crate::inner::seeding::secrets::GlobalSecrets;
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct RandomState<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> {
seed: u64,
secrets: GlobalSecrets,
}
impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED> {
#[inline]
pub fn new() -> Self {
Self {
seed: super::seeding::seed::get_seed(),
secrets: GlobalSecrets::new(),
}
}
}
#[cfg(target_has_atomic = "ptr")]
impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> Default for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<const AVALANCHE: bool, const SPONGE: bool, const COMPACT: bool, const PROTECTED: bool> BuildHasher for RandomState<AVALANCHE, SPONGE, COMPACT, PROTECTED> {
type Hasher = RapidHasher<AVALANCHE, SPONGE, COMPACT, PROTECTED>;
#[inline(always)]
fn build_hasher(&self) -> Self::Hasher {
RapidHasher::new_precomputed_seed(self.seed, self.secrets.get())
}
}
#[cfg(test)]
mod tests {
use core::hash::BuildHasher;
type RandomState = super::RandomState<false, true, false, false>;
#[test]
fn test_random_state() {
assert_eq!(core::mem::size_of::<RandomState>(), 8);
let state1 = RandomState::new();
let state2 = RandomState::new();
let finish1a = state1.hash_one(b"hello");
let finish1b = state1.hash_one(b"hello");
let finish2a = state2.hash_one(b"hello");
assert_eq!(finish1a, finish1b);
assert_ne!(finish1a, finish2a);
}
}