1#[derive(Debug, Clone)]
9pub struct Rng {
10 inner: fastrand::Rng,
11}
12
13impl Rng {
14 #[must_use]
17 pub fn from_seed(seed: u64) -> Self {
18 Self {
19 inner: fastrand::Rng::with_seed(seed),
20 }
21 }
22
23 pub fn f32(&mut self) -> f32 {
25 self.inner.f32()
26 }
27
28 pub fn u32(&mut self, range: std::ops::Range<u32>) -> u32 {
30 self.inner.u32(range)
31 }
32
33 pub fn i32(&mut self, range: std::ops::Range<i32>) -> i32 {
35 self.inner.i32(range)
36 }
37
38 pub fn usize(&mut self, range: std::ops::Range<usize>) -> usize {
40 self.inner.usize(range)
41 }
42
43 pub fn bool(&mut self) -> bool {
45 self.inner.bool()
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52 use wasm_bindgen_test::wasm_bindgen_test;
53
54 #[wasm_bindgen_test(unsupported = test)]
56 fn same_seed_same_sequence() {
57 let mut a = Rng::from_seed(42);
58 let mut b = Rng::from_seed(42);
59 for _ in 0..100 {
60 assert_eq!(a.u32(0..1000), b.u32(0..1000));
61 assert_eq!(a.f32().to_bits(), b.f32().to_bits());
62 assert_eq!(a.bool(), b.bool());
63 }
64 }
65
66 #[wasm_bindgen_test(unsupported = test)]
68 fn different_seeds_diverge() {
69 let mut a = Rng::from_seed(1);
70 let mut b = Rng::from_seed(2);
71 let sa: Vec<u32> = (0..16).map(|_| a.u32(0..u32::MAX)).collect();
72 let sb: Vec<u32> = (0..16).map(|_| b.u32(0..u32::MAX)).collect();
73 assert_ne!(sa, sb);
74 }
75
76 #[wasm_bindgen_test(unsupported = test)]
78 fn values_stay_in_range() {
79 let mut rng = Rng::from_seed(7);
80 for _ in 0..1000 {
81 let v = rng.usize(3..9);
82 assert!((3..9).contains(&v));
83 let f = rng.f32();
84 assert!((0.0..1.0).contains(&f));
85 }
86 }
87}