swage_core/util/
rng.rs

1use rand::{RngCore, SeedableRng, rngs::StdRng};
2use serde::Serialize;
3
4/// Seedable random number generator.
5///
6/// Wraps StdRng to provide deterministic randomness from a seed value.
7#[derive(Debug, Serialize, PartialEq, Eq)]
8pub struct Rng {
9    seed: u64,
10    #[serde(skip_serializing)]
11    rng: StdRng,
12}
13
14impl Rng {
15    /// Creates a new RNG from a seed value.
16    ///
17    /// # Arguments
18    ///
19    /// * `seed` - Seed value for deterministic random generation
20    pub fn from_seed(seed: u64) -> Self {
21        Self {
22            seed,
23            rng: StdRng::seed_from_u64(seed),
24        }
25    }
26}
27
28impl RngCore for Rng {
29    fn next_u32(&mut self) -> u32 {
30        self.rng.next_u32()
31    }
32
33    fn next_u64(&mut self) -> u64 {
34        self.rng.next_u64()
35    }
36
37    fn fill_bytes(&mut self, dest: &mut [u8]) {
38        self.rng.fill_bytes(dest);
39    }
40}
41
42impl Clone for Rng {
43    fn clone(&self) -> Self {
44        Self::from_seed(self.seed)
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use crate::util::Rng;
51    use rand::RngCore;
52
53    #[test]
54    fn test_rng_clone() {
55        let mut rng = Rng::from_seed(0x42);
56        let a = rng.next_u64();
57        let mut cloned_rng = rng.clone();
58        let b = cloned_rng.next_u64();
59        assert_eq!(a, b, "Cloned Rng should start with the same seed");
60    }
61}