1#![cfg_attr(not(any(test, feature = "std")), no_std)]
2
3use crate::combinator::{AndThenGenerator, FilterGenerator, FilterMapGenerator, MapGenerator};
4use core::marker::PhantomData;
5
6#[cfg(test)]
7#[macro_use]
8mod testing;
9
10mod uniform;
11
12#[cfg(feature = "either")]
13pub use either;
14
15#[cfg(feature = "alloc")]
16extern crate alloc;
17
18#[cfg(feature = "alloc")]
19#[path = "alloc/mod.rs"]
20#[macro_use]
21pub mod alloc_generators;
22
23#[cfg(any(test, feature = "std", feature = "arbitrary"))]
24extern crate std;
25
26#[cfg(any(test, feature = "std"))]
27#[path = "std/mod.rs"]
28pub mod std_generators;
29
30pub use bolero_generator_derive::*;
31#[cfg(feature = "arbitrary")]
32pub mod arbitrary;
33
34#[cfg(feature = "any")]
35pub mod any;
36pub mod array;
37pub mod atomic;
38pub mod bool;
39pub mod bounded;
40pub mod char;
41pub mod combinator;
42pub mod driver;
43#[cfg(any(test, kani))]
44pub mod kani;
45pub mod num;
46pub mod one_of;
47pub mod prelude;
48pub mod range;
49pub mod result;
50pub mod time;
51#[cfg(feature = "std")]
52pub mod trace;
53pub mod tuple;
54
55#[cfg(feature = "arbitrary")]
56pub use crate::arbitrary::gen_arbitrary;
57
58pub use crate::driver::Driver;
59
60pub trait TypeGenerator: 'static + Sized {
62 fn generate<D: Driver>(driver: &mut D) -> Option<Self>;
64
65 #[inline]
67 fn mutate<D: Driver>(&mut self, driver: &mut D) -> Option<()> {
68 match Self::generate(driver) {
69 Some(next) => {
70 let prev = core::mem::replace(self, next);
71 Self::driver_cache(prev, driver);
72 Some(())
73 }
74 None => None,
75 }
76 }
77
78 #[inline(always)]
79 fn driver_cache<D: Driver>(self, driver: &mut D) {
80 let _ = driver;
81 }
82
83 #[inline]
85 fn produce() -> TypeValueGenerator<Self> {
86 produce()
87 }
88
89 #[deprecated = "Use `produce` instead (`gen` conflicts with edition2024)"]
90 #[inline]
91 fn gen() -> TypeValueGenerator<Self> {
92 produce()
93 }
94}
95
96pub trait ValueGenerator: Sized {
98 type Output: 'static;
99
100 fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output>;
102
103 #[inline]
105 fn mutate<D: Driver>(&self, driver: &mut D, value: &mut Self::Output) -> Option<()> {
106 match self.generate(driver) {
107 Some(next) => {
108 let prev = core::mem::replace(value, next);
109 self.driver_cache(driver, prev);
110 Some(())
111 }
112 None => None,
113 }
114 }
115
116 #[inline(always)]
117 fn driver_cache<D: Driver>(&self, driver: &mut D, value: Self::Output) {
118 let _ = driver;
119 let _ = value;
120 }
121
122 fn map_gen<F: Fn(Self::Output) -> T, T>(self, map: F) -> MapGenerator<Self, F> {
124 MapGenerator {
125 generator: self,
126 map,
127 }
128 }
129
130 fn and_then_gen<F: Fn(Self::Output) -> T, T: ValueGenerator>(
132 self,
133 and_then: F,
134 ) -> AndThenGenerator<Self, F> {
135 AndThenGenerator {
136 generator: self,
137 and_then,
138 }
139 }
140
141 fn filter_gen<F: Fn(&Self::Output) -> bool>(self, filter: F) -> FilterGenerator<Self, F> {
143 FilterGenerator {
144 generator: self,
145 filter,
146 }
147 }
148
149 fn filter_map_gen<F: Fn(Self::Output) -> Option<T>, T>(
151 self,
152 filter_map: F,
153 ) -> FilterMapGenerator<Self, F> {
154 FilterMapGenerator {
155 generator: self,
156 filter_map,
157 }
158 }
159
160 #[cfg(feature = "std")]
162 #[inline]
163 fn trace(self) -> trace::Trace<Self> {
164 trace::Trace::new(self)
165 }
166}
167
168impl<T: ValueGenerator> ValueGenerator for &T {
169 type Output = T::Output;
170
171 #[inline]
172 fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output> {
173 (*self).generate(driver)
174 }
175
176 #[inline]
177 fn mutate<D: Driver>(&self, driver: &mut D, value: &mut Self::Output) -> Option<()> {
178 (*self).mutate(driver, value)
179 }
180
181 #[inline]
182 fn driver_cache<D: Driver>(&self, driver: &mut D, value: Self::Output) {
183 (*self).driver_cache(driver, value)
184 }
185}
186
187pub trait TypeGeneratorWithParams {
189 type Output: ValueGenerator;
190
191 fn gen_with() -> Self::Output;
192}
193
194#[derive(Debug)]
196pub struct TypeValueGenerator<T: TypeGenerator>(PhantomData<T>);
197
198impl<T: TypeGenerator> Copy for TypeValueGenerator<T> {}
200
201impl<T: TypeGenerator> Clone for TypeValueGenerator<T> {
202 fn clone(&self) -> Self {
203 *self
204 }
205}
206
207impl<T: TypeGenerator> Default for TypeValueGenerator<T> {
208 fn default() -> Self {
209 Self(PhantomData)
210 }
211}
212
213impl<T: TypeGenerator + TypeGeneratorWithParams> TypeValueGenerator<T> {
214 pub fn with(self) -> <T as TypeGeneratorWithParams>::Output {
215 T::gen_with()
216 }
217}
218
219impl<T: TypeGenerator> ValueGenerator for TypeValueGenerator<T> {
220 type Output = T;
221
222 #[inline(always)]
223 fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output> {
224 T::generate(driver)
225 }
226
227 #[inline(always)]
228 fn mutate<D: Driver>(&self, driver: &mut D, value: &mut T) -> Option<()> {
229 T::mutate(value, driver)
230 }
231
232 #[inline(always)]
233 fn driver_cache<D: Driver>(&self, driver: &mut D, value: T) {
234 T::driver_cache(value, driver)
235 }
236}
237
238#[inline]
240pub fn produce<T: TypeGenerator>() -> TypeValueGenerator<T> {
241 TypeValueGenerator(PhantomData)
242}
243
244#[deprecated = "Use `produce` instead (`gen` conflicts with edition2024)"]
246#[inline]
247pub fn gen<T: TypeGenerator>() -> TypeValueGenerator<T> {
248 TypeValueGenerator(PhantomData)
249}
250
251#[inline]
253pub fn produce_with<T: TypeGeneratorWithParams>() -> T::Output {
254 T::gen_with()
255}
256
257#[deprecated = "Use `produce_with` instead (`gen_with` conflicts with edition2024)"]
259#[inline]
260pub fn gen_with<T: TypeGeneratorWithParams>() -> T::Output {
261 produce_with::<T>()
262}
263
264pub use one_of::{one_of, one_value_of};
265
266impl<T: 'static> ValueGenerator for PhantomData<T> {
267 type Output = Self;
268
269 fn generate<D: Driver>(&self, _driver: &mut D) -> Option<Self::Output> {
270 Some(PhantomData)
271 }
272}
273
274impl<T: 'static> TypeGenerator for PhantomData<T> {
275 fn generate<D: Driver>(_driver: &mut D) -> Option<Self> {
276 Some(PhantomData)
277 }
278}
279
280pub struct Constant<T> {
281 value: T,
282}
283
284impl<T: 'static + Clone> ValueGenerator for Constant<T> {
285 type Output = T;
286
287 fn generate<D: Driver>(&self, _driver: &mut D) -> Option<Self::Output> {
288 Some(self.value.clone())
289 }
290}
291
292#[inline]
294pub fn constant<T: Clone>(value: T) -> Constant<T> {
295 Constant { value }
296}