1#[cfg(feature = "chacha")]
2pub use chacha::{ChaCha, ChaCha12, ChaCha20, ChaCha8};
3#[cfg(feature = "pcg64")]
4pub use pcg64::Pcg64;
5#[cfg(feature = "wyrand")]
6pub use wyrand::WyRand;
7
8use crate::gen::{RandomGen, RandomRange};
9use core::ops::RangeBounds;
10
11#[cfg(feature = "wyrand")]
14pub mod wyrand;
15
16#[cfg(feature = "pcg64")]
19pub mod pcg64;
20
21#[cfg(feature = "chacha")]
24pub mod chacha;
25
26pub trait Rng<const OUTPUT: usize>: Clone {
28 fn rand(&mut self) -> [u8; OUTPUT];
30
31 fn generate<Generated>(&mut self) -> Generated
33 where
34 Generated: RandomGen<Self, OUTPUT>,
35 {
36 Generated::random(self)
37 }
38
39 fn fill_bytes<Bytes>(&mut self, mut buffer: Bytes)
41 where
42 Bytes: AsMut<[u8]>,
43 {
44 let mut buffer = buffer.as_mut();
45 let mut length = buffer.len();
46 while length > 0 {
47 let chunk = self.rand();
48 let generated = chunk.len().min(length);
49 buffer[..generated].copy_from_slice(&chunk[..generated]);
50 buffer = &mut buffer[generated..];
51 length -= generated;
52 }
53 }
54
55 fn fill<Contents, Array>(&mut self, mut target: Array)
57 where
58 Contents: RandomGen<Self, OUTPUT>,
59 Array: AsMut<[Contents]>,
60 {
61 let target = target.as_mut();
62 target.iter_mut().for_each(|entry| *entry = self.generate());
63 }
64
65 fn generate_range<Number, Bounds>(&mut self, range: Bounds) -> Number
67 where
68 Number: RandomRange<Self, OUTPUT>,
69 Bounds: RangeBounds<Number>,
70 {
71 Number::random_range(self, range)
72 }
73
74 fn shuffle<Contents, Array>(&mut self, mut target: Array)
76 where
77 Array: AsMut<[Contents]>,
78 {
79 let target = target.as_mut();
80 let target_len = target.len();
81 for idx in (1..target_len).rev() {
82 let random_idx = self.generate_range(0..idx + 1);
83 target.swap(idx, random_idx);
84 }
85 }
86}
87
88pub trait SeedableRng<const SEED_SIZE: usize, const OUTPUT: usize>: Rng<OUTPUT> {
90 fn reseed(&mut self, seed: [u8; SEED_SIZE]);
92}