osom_lib_rand/randomness_sources/
os_randomness_source.rs1use core::marker::PhantomData;
2
3use crate::{number::{Number, NumberType}, traits::RandomnessSource};
4
5#[inline(always)]
6fn next_os_number<ANumber: Number>() -> ANumber {
7 match ANumber::NUMBER_TYPE {
8 NumberType::U32 => {
9 let no = getrandom::u32().expect("Failed to get u32 random number from OS");
10 ANumber::from_u32(no)
11 }
12 NumberType::U64 => {
13 let no = getrandom::u64().expect("Failed to get u64 random number from OS");
14 unsafe { ANumber::from_u64_unchecked(no) }
15 }
16 NumberType::U128 => {
17 let mut array = [0u8; size_of::<u128>()];
18 getrandom::fill(&mut array).expect("Failed to get u128 random number from OS");
19 let no = u128::from_ne_bytes(array);
20 unsafe { ANumber::from_u128_unchecked(no) }
21 }
22 }
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
29#[must_use]
30#[repr(transparent)]
31pub struct OsRandomnessSource<ANumber: Number> {
32 _phantom: PhantomData<ANumber>,
33}
34
35impl<ANumber: Number> Default for OsRandomnessSource<ANumber> {
36 fn default() -> Self {
37 Self {
38 _phantom: PhantomData,
39 }
40 }
41}
42
43impl<ANumber: Number> RandomnessSource for OsRandomnessSource<ANumber> {
44 type TNumber = ANumber;
45
46 fn next_number(&mut self) -> Self::TNumber {
47 next_os_number()
48 }
49
50 fn fill_bytes(&mut self, bytes: &mut [u8]) {
51 if bytes.is_empty() {
52 return;
53 }
54
55 getrandom::fill(bytes).expect("Failed to fill bytes from OS");
56 }
57}