bolero_generator/
lib.rs

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
60/// Generate a value for a given type
61pub trait TypeGenerator: 'static + Sized {
62    /// Generates a value with the given driver
63    fn generate<D: Driver>(driver: &mut D) -> Option<Self>;
64
65    /// Mutates an existing value with the given driver
66    #[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    /// Returns a generator for a given type
84    #[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
96/// Generate a value with a parameterized generator
97pub trait ValueGenerator: Sized {
98    type Output: 'static;
99
100    /// Generates a value with the given driver
101    fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output>;
102
103    /// Mutates an existing value with the given driver
104    #[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    /// Map the value of a generator
123    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    /// Map the value of a generator with a new generator
131    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    /// Filter the value of a generator
142    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    /// Filter the value of a generator and map it to something else
150    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    /// Traces generated values to `stderr`
161    #[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
187/// Convert a type generator into the default value generator
188pub trait TypeGeneratorWithParams {
189    type Output: ValueGenerator;
190
191    fn gen_with() -> Self::Output;
192}
193
194/// Non-parameterized ValueGenerator given a TypeGenerator
195#[derive(Debug)]
196pub struct TypeValueGenerator<T: TypeGenerator>(PhantomData<T>);
197
198// this needs to be implemented manually so it doesn't force `T: Copy`
199impl<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/// Generate a value for a given type
239#[inline]
240pub fn produce<T: TypeGenerator>() -> TypeValueGenerator<T> {
241    TypeValueGenerator(PhantomData)
242}
243
244/// Generate a value for a given type
245#[deprecated = "Use `produce` instead (`gen` conflicts with edition2024)"]
246#[inline]
247pub fn gen<T: TypeGenerator>() -> TypeValueGenerator<T> {
248    TypeValueGenerator(PhantomData)
249}
250
251/// Generate a value for a given type with additional constraints
252#[inline]
253pub fn produce_with<T: TypeGeneratorWithParams>() -> T::Output {
254    T::gen_with()
255}
256
257/// Generate a value for a given type
258#[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/// Always generate the same value
293#[inline]
294pub fn constant<T: Clone>(value: T) -> Constant<T> {
295    Constant { value }
296}