1pub fn fill(bs: &mut [u8]) -> crate::Result<()> {
7 getrandom::getrandom(bs).map_err(|e| crate::Error::SystemError {
8 call: "getrandom::getrandom",
9 raw_os_error: e.raw_os_error(),
10 })
11}
12
13pub unsafe fn gen<T: Sized + Copy>() -> crate::Result<T> {
19 let mut t = core::mem::MaybeUninit::uninit();
20 fill(core::slice::from_raw_parts_mut(
21 t.as_mut_ptr() as *mut u8,
22 core::mem::size_of::<T>(),
23 ))?;
24 Ok(t.assume_init())
25}
26
27#[cfg(test)]
28mod tests {
29 use super::*;
30
31 #[test]
32 fn test_fill() {
33 for _ in 0..ITERATIONS {
34 for size in TEST_SIZES.iter() {
35 let mut buf = vec![0; *size];
36 fill(&mut buf).unwrap();
37 check_uniform_dist(&buf)
38 }
39 }
40 }
41 const TEST_SIZES: &[usize] = &[1024 * 1024, 4 * 1024 * 1024, (4 * 1024 * 1024) + 15];
42 const ITERATIONS: usize = 8;
43
44 fn check_uniform_dist(buf: &[u8]) {
45 let mut dist = vec![0f64; 256];
46 buf.iter().for_each(|b| dist[*b as usize] += 1.0);
47
48 let estimated_avg = (buf.len() as f64) / 256.0;
49 let (estimated_min, estimated_max) = (estimated_avg * 0.9, estimated_avg * 1.1);
50 dist.iter().for_each(|d| {
51 assert!(*d > estimated_min, "{} is not > {}", *d, estimated_min);
52 assert!(*d < estimated_max, "{} is not < {}", *d, estimated_max);
53 });
54 }
55
56 #[test]
57 #[should_panic]
58 fn verify_check_uniform_dist() {
59 check_uniform_dist(&[0; (4 * 1024 * 1024) + 15])
60 }
61}