bolero_generator/driver/
rng.rs1use super::*;
2
3#[cfg(feature = "alloc")]
4pub(crate) use buffer_alloc::Buffer;
5#[cfg(not(feature = "alloc"))]
6pub(crate) use buffer_no_alloc::Buffer;
7
8#[derive(Debug)]
9pub struct Rng<R: TryRngCore> {
10 rng: R,
11 depth: usize,
12 max_depth: usize,
13 consumed_len: usize,
14 max_len: usize,
15 #[allow(dead_code)] buffer: Buffer,
17}
18
19impl<R: TryRngCore> Rng<R> {
20 pub fn new(rng: R, options: &Options) -> Self {
21 Self {
22 rng,
23 depth: 0,
24 max_depth: options.max_depth_or_default(),
25 consumed_len: 0,
26 max_len: options.max_len_or_default(),
27 buffer: Default::default(),
28 }
29 }
30
31 #[inline]
32 fn fill_bytes(&mut self, bytes: &mut [u8]) -> Option<()> {
33 let len = bytes.len().min(self.remaining_len());
34 let (to_rng, to_fill) = bytes.split_at_mut(len);
35 fill_bytes(&mut self.rng, to_rng)?;
36 to_fill.fill(0);
37 Some(())
38 }
39
40 #[inline]
41 fn has_remaining(&self) -> bool {
42 self.consumed_len < self.max_len
43 }
44
45 #[inline]
46 fn remaining_len(&self) -> usize {
47 self.max_len.saturating_sub(self.consumed_len)
48 }
49
50 #[inline]
51 fn fill_buffer(&mut self, len: usize) -> Option<&[u8]> {
52 self.buffer.fill(len, &mut self.rng)?;
53 Some(self.buffer.slice_mut(len))
54 }
55}
56
57impl<R: TryRngCore> AsRef<R> for Rng<R> {
58 #[inline]
59 fn as_ref(&self) -> &R {
60 &self.rng
61 }
62}
63
64#[inline]
65fn fill_bytes<R: TryRngCore>(rng: &mut R, bytes: &mut [u8]) -> Option<()> {
66 if TryRngCore::try_fill_bytes(rng, bytes).is_err() {
67 for byte in bytes.iter_mut() {
69 *byte = 0;
70 }
71 }
72
73 Some(())
74}
75
76macro_rules! impl_sample {
77 ($sample:ident, $ty:ty, $inner:ident) => {
78 #[inline(always)]
79 fn $sample(&mut self) -> Option<$ty> {
80 if self.has_remaining() {
81 self.consumed_len += core::mem::size_of::<$ty>();
82 Some(self.rng.$inner().unwrap_or_default() as $ty)
83 } else {
84 Some(0)
85 }
86 }
87 };
88}
89
90impl<R: TryRngCore> FillBytes for Rng<R> {
91 const SHOULD_SHRINK: bool = false;
93
94 #[inline]
95 fn peek_bytes(&mut self, _offset: usize, bytes: &mut [u8]) -> Option<()> {
96 self.fill_bytes(bytes)
97 }
98
99 #[inline(always)]
100 fn consume_bytes(&mut self, consumed: usize) {
101 self.consumed_len += consumed;
102 }
103
104 #[inline(always)]
105 fn sample_bool(&mut self) -> Option<bool> {
106 if self.has_remaining() {
107 self.consumed_len += 1;
108 let value = self.rng.try_next_u32().unwrap_or_default();
109 Some(value < (u32::MAX / 2))
110 } else {
111 Some(false)
112 }
113 }
114
115 impl_sample!(sample_u8, u8, try_next_u32);
116 impl_sample!(sample_i8, i8, try_next_u32);
117 impl_sample!(sample_u16, u16, try_next_u32);
118 impl_sample!(sample_i16, i16, try_next_u32);
119 impl_sample!(sample_u32, u32, try_next_u32);
120 impl_sample!(sample_i32, i32, try_next_u32);
121 impl_sample!(sample_u64, u64, try_next_u64);
122 impl_sample!(sample_i64, i64, try_next_u64);
123 impl_sample!(sample_usize, usize, try_next_u64);
124 impl_sample!(sample_isize, isize, try_next_u64);
125}
126
127impl<R: TryRngCore> Driver for Rng<R> {
128 gen_from_bytes!();
129
130 #[inline]
131 fn depth(&self) -> usize {
132 self.depth
133 }
134
135 #[inline]
136 fn set_depth(&mut self, depth: usize) {
137 self.depth = depth;
138 }
139
140 #[inline]
141 fn max_depth(&self) -> usize {
142 self.max_depth
143 }
144
145 #[inline]
146 fn gen_from_bytes<Hint, Gen, T>(&mut self, hint: Hint, mut produce: Gen) -> Option<T>
147 where
148 Hint: FnOnce() -> (usize, Option<usize>),
149 Gen: FnMut(&[u8]) -> Option<(usize, T)>,
150 {
151 let (min, max) = hint();
152
153 let max = max
154 .unwrap_or(usize::MAX)
155 .clamp(min, self.remaining_len())
157 .min(Buffer::MAX_CAPACITY);
158
159 let len = self.gen_usize(Bound::Included(&min), Bound::Included(&max))?;
160 let bytes = self.fill_buffer(len)?;
161 let (consumed, value) = produce(bytes)?;
162 self.consume_bytes(consumed);
163 self.buffer.clear();
164 Some(value)
165 }
166}
167
168#[cfg(feature = "alloc")]
169mod buffer_alloc {
170 use super::*;
171
172 #[derive(Clone, Debug, Default)]
173 pub struct Buffer {
174 bytes: alloc::vec::Vec<u8>,
175 }
176
177 impl Buffer {
178 pub const MAX_CAPACITY: usize = isize::MAX as _;
179
180 #[inline]
181 pub fn fill<R: TryRngCore>(&mut self, len: usize, rng: &mut R) -> Option<()> {
182 let data = &mut self.bytes;
183
184 let initial_len = data.len();
185
186 if initial_len >= len {
188 return Some(());
189 }
190
191 data.try_reserve(len).ok()?;
193 data.resize(len, 0);
194 fill_bytes(rng, &mut data[initial_len..])?;
195
196 Some(())
197 }
198
199 #[inline]
200 pub fn slice_mut(&mut self, len: usize) -> &mut [u8] {
201 &mut self.bytes[..len]
202 }
203
204 #[inline]
205 pub fn clear(&mut self) {
206 self.bytes.clear();
207 }
208 }
209}
210
211#[cfg_attr(feature = "alloc", allow(dead_code))]
212mod buffer_no_alloc {
213 use super::*;
214
215 #[derive(Clone, Debug)]
216 pub struct Buffer {
217 bytes: [u8; Self::MAX_CAPACITY],
218 len: usize,
219 }
220
221 impl Default for Buffer {
222 fn default() -> Self {
223 Self {
224 bytes: [0; Self::MAX_CAPACITY],
225 len: Default::default(),
226 }
227 }
228 }
229
230 impl Buffer {
231 pub const MAX_CAPACITY: usize = 256;
232
233 #[inline]
234 pub fn fill<R: TryRngCore>(&mut self, len: usize, rng: &mut R) -> Option<()> {
235 if cfg!(test) {
236 assert!(len <= Self::MAX_CAPACITY);
237 }
238
239 let initial_len = self.len;
240
241 if initial_len >= len {
243 return Some(());
244 }
245
246 fill_bytes(rng, &mut self.bytes[initial_len..])?;
248 self.len = len;
249
250 Some(())
251 }
252
253 #[inline]
254 pub fn slice_mut(&mut self, len: usize) -> &mut [u8] {
255 &mut self.bytes[..len]
256 }
257
258 #[inline]
259 pub fn clear(&mut self) {
260 self.len = 0;
261 }
262 }
263}