osom_lib_prng/
stream_prng.rs1use core::ops::RangeBounds;
4
5use osom_lib_reprc::{macros::reprc, traits::ReprC};
6
7use crate::{
8 prngs::helpers::{
9 generate_f32_in_range, generate_f64_in_range, generate_i32_in_range, generate_i64_in_range,
10 generate_u32_in_range, generate_u64_in_range,
11 },
12 traits::{PRNConcreteBoundedGenerator, PRNConcreteGenerator, PRNGenerator, PRStream, Seedable},
13};
14
15#[derive(Debug, PartialEq, Eq, Clone)]
18#[reprc]
19pub struct StreamPRNG<T: PRStream> {
20 stream: T,
21}
22
23impl<T: PRStream> StreamPRNG<T> {
24 #[inline(always)]
26 pub fn new(stream: T) -> Self {
27 Self { stream }
28 }
29}
30
31#[allow(clippy::cast_possible_truncation)]
32impl<T: PRStream> PRNGenerator for StreamPRNG<T> {
33 unsafe fn fill_raw(&mut self, dst_ptr: *mut u8, dst_len: usize) {
34 unsafe { self.stream.fill_raw(dst_ptr, dst_len) };
35 }
36}
37
38impl<const N: usize, T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for [u8; N] {
39 #[inline(always)]
40 fn generate(generator: &mut StreamPRNG<T>) -> Self {
41 const {
42 assert!(size_of::<Self>() == N);
43 }
44 if N == 0 {
45 return [0u8; N];
46 }
47 let mut item = core::mem::MaybeUninit::<Self>::uninit();
48 unsafe {
49 generator.fill_raw(item.as_mut_ptr().cast(), N);
50 item.assume_init()
51 }
52 }
53}
54
55impl<T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for bool {
56 fn generate(generator: &mut StreamPRNG<T>) -> Self {
57 (generator.generate::<u8>() & 1) == 1
58 }
59}
60
61impl<T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for u8 {
62 fn generate(generator: &mut StreamPRNG<T>) -> Self {
63 u8::from_le_bytes(generator.generate::<[u8; 1]>())
64 }
65}
66
67impl<T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for i8 {
68 fn generate(generator: &mut StreamPRNG<T>) -> Self {
69 i8::from_le_bytes(generator.generate::<[u8; 1]>())
70 }
71}
72
73impl<T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for u16 {
74 fn generate(generator: &mut StreamPRNG<T>) -> Self {
75 u16::from_le_bytes(generator.generate::<[u8; 2]>())
76 }
77}
78
79impl<T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for i16 {
80 fn generate(generator: &mut StreamPRNG<T>) -> Self {
81 i16::from_le_bytes(generator.generate::<[u8; 2]>())
82 }
83}
84
85impl<T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for u32 {
86 fn generate(generator: &mut StreamPRNG<T>) -> Self {
87 u32::from_le_bytes(generator.generate::<[u8; 4]>())
88 }
89}
90
91impl<T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for i32 {
92 fn generate(generator: &mut StreamPRNG<T>) -> Self {
93 i32::from_le_bytes(generator.generate::<[u8; 4]>())
94 }
95}
96
97impl<T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for u64 {
98 fn generate(generator: &mut StreamPRNG<T>) -> Self {
99 u64::from_le_bytes(generator.generate::<[u8; 8]>())
100 }
101}
102
103impl<T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for i64 {
104 fn generate(generator: &mut StreamPRNG<T>) -> Self {
105 i64::from_le_bytes(generator.generate::<[u8; 8]>())
106 }
107}
108
109impl<T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for u128 {
110 fn generate(generator: &mut StreamPRNG<T>) -> Self {
111 u128::from_le_bytes(generator.generate::<[u8; 16]>())
112 }
113}
114
115impl<T: PRStream> PRNConcreteGenerator<StreamPRNG<T>> for i128 {
116 fn generate(generator: &mut StreamPRNG<T>) -> Self {
117 i128::from_le_bytes(generator.generate::<[u8; 16]>())
118 }
119}
120
121impl<T: PRStream> PRNConcreteBoundedGenerator<StreamPRNG<T>> for u32 {
122 fn generate<TBounds: RangeBounds<Self>>(generator: &mut StreamPRNG<T>, range: TBounds) -> Self {
123 generate_u32_in_range(generator, range)
124 }
125}
126
127impl<T: PRStream> PRNConcreteBoundedGenerator<StreamPRNG<T>> for u64 {
128 fn generate<TBounds: RangeBounds<Self>>(generator: &mut StreamPRNG<T>, range: TBounds) -> Self {
129 generate_u64_in_range(generator, range)
130 }
131}
132
133impl<T: PRStream> PRNConcreteBoundedGenerator<StreamPRNG<T>> for i32 {
134 fn generate<TBounds: RangeBounds<Self>>(generator: &mut StreamPRNG<T>, range: TBounds) -> Self {
135 generate_i32_in_range(generator, range)
136 }
137}
138
139impl<T: PRStream> PRNConcreteBoundedGenerator<StreamPRNG<T>> for i64 {
140 fn generate<TBounds: RangeBounds<Self>>(generator: &mut StreamPRNG<T>, range: TBounds) -> Self {
141 generate_i64_in_range(generator, range)
142 }
143}
144
145impl<T: PRStream> PRNConcreteBoundedGenerator<StreamPRNG<T>> for f32 {
146 fn generate<TBounds: RangeBounds<Self>>(generator: &mut StreamPRNG<T>, range: TBounds) -> Self {
147 generate_f32_in_range(generator, range)
148 }
149}
150
151impl<T: PRStream> PRNConcreteBoundedGenerator<StreamPRNG<T>> for f64 {
152 fn generate<TBounds: RangeBounds<Self>>(generator: &mut StreamPRNG<T>, range: TBounds) -> Self {
153 generate_f64_in_range(generator, range)
154 }
155}
156
157impl<TSeed: ReprC + Copy, T: PRStream + Seedable<TSeed>> Seedable<TSeed> for StreamPRNG<T> {
158 fn with_seed(seed: TSeed) -> Self {
159 Self::new(T::with_seed(seed))
160 }
161}