Skip to content
File

Blob: firmware/vendor/str0m/src/_internal_test_exports/rng.rs

rust56 lines
1pub struct Rng<'a>(&'a [u8], usize);
2 
3macro_rules! rng_primary {
4 ($unit:tt, $above:tt) => {
5 pub fn $unit(&mut self, max: $unit) -> Option<$unit> {
6 const X: usize = std::mem::size_of::<$unit>();
7 let bytes = self.array::<X>()?;
8 let u = $unit::from_be_bytes(bytes);
9 Some(if max == $unit::MAX {
10 u
11 } else {
12 ((u as $above * max as $above) / $unit::MAX as $above) as $unit
13 })
14 }
15 };
16}
17 
18impl<'a> Rng<'a> {
19 pub fn new(data: &'a [u8]) -> Self {
20 Self(data, 0)
21 }
22 
23 pub fn slice(&mut self, n: usize) -> Option<&[u8]> {
24 let start = self.1;
25 let end = self.1 + n;
26 
27 if end > self.0.len() {
28 // First that hits limit ends anymore data.
29 self.1 = self.0.len();
30 return None;
31 }
32 
33 self.1 = end;
34 
35 Some(&self.0[start..end])
36 }
37 
38 pub fn array<const N: usize>(&mut self) -> Option<[u8; N]> {
39 let slice = self.slice(N)?;
40 
41 let mut arr = [0_u8; N];
42 arr.copy_from_slice(slice);
43 
44 Some(arr)
45 }
46 
47 pub fn bool(&mut self) -> Option<bool> {
48 Some(self.array::<1>()?[0] < 128)
49 }
50 
51 rng_primary!(u8, u16);
52 rng_primary!(u32, u64);
53 rng_primary!(u64, u128);
54 rng_primary!(usize, u128);
55}