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;
45#[cfg(feature = "std")]
46pub mod net;
47pub mod num;
48pub mod one_of;
49pub mod prelude;
50pub mod range;
51pub mod result;
52pub mod time;
53#[cfg(feature = "std")]
54pub mod trace;
55pub mod tuple;
56
57#[cfg(feature = "arbitrary")]
58pub use crate::arbitrary::gen_arbitrary;
59
60pub use crate::driver::Driver;
61
62/// Generate a value for a given type
63pub trait TypeGenerator: 'static + Sized {
64    /// Generates a value with the given driver
65    fn generate<D: Driver>(driver: &mut D) -> Option<Self>;
66
67    /// Mutates an existing value with the given driver
68    #[inline]
69    fn mutate<D: Driver>(&mut self, driver: &mut D) -> Option<()> {
70        match Self::generate(driver) {
71            Some(next) => {
72                let prev = core::mem::replace(self, next);
73                Self::driver_cache(prev, driver);
74                Some(())
75            }
76            None => None,
77        }
78    }
79
80    #[inline(always)]
81    fn driver_cache<D: Driver>(self, driver: &mut D) {
82        let _ = driver;
83    }
84
85    /// Returns a generator for a given type
86    #[inline]
87    fn produce() -> TypeValueGenerator<Self> {
88        produce()
89    }
90
91    #[deprecated = "Use `produce` instead (`gen` conflicts with edition2024)"]
92    #[inline]
93    fn gen() -> TypeValueGenerator<Self> {
94        produce()
95    }
96}
97
98/// Generate a value with a parameterized generator
99pub trait ValueGenerator: Sized {
100    type Output: 'static;
101
102    /// Generates a value with the given driver
103    fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output>;
104
105    /// Mutates an existing value with the given driver
106    #[inline]
107    fn mutate<D: Driver>(&self, driver: &mut D, value: &mut Self::Output) -> Option<()> {
108        match self.generate(driver) {
109            Some(next) => {
110                let prev = core::mem::replace(value, next);
111                self.driver_cache(driver, prev);
112                Some(())
113            }
114            None => None,
115        }
116    }
117
118    #[inline(always)]
119    fn driver_cache<D: Driver>(&self, driver: &mut D, value: Self::Output) {
120        let _ = driver;
121        let _ = value;
122    }
123
124    /// Map the value of a generator
125    fn map_gen<F: Fn(Self::Output) -> T, T>(self, map: F) -> MapGenerator<Self, F> {
126        MapGenerator {
127            generator: self,
128            map,
129        }
130    }
131
132    /// Map the value of a generator with a new generator
133    fn and_then_gen<F: Fn(Self::Output) -> T, T: ValueGenerator>(
134        self,
135        and_then: F,
136    ) -> AndThenGenerator<Self, F> {
137        AndThenGenerator {
138            generator: self,
139            and_then,
140        }
141    }
142
143    /// Filter the value of a generator
144    fn filter_gen<F: Fn(&Self::Output) -> bool>(self, filter: F) -> FilterGenerator<Self, F> {
145        FilterGenerator {
146            generator: self,
147            filter,
148        }
149    }
150
151    /// Filter the value of a generator and map it to something else
152    fn filter_map_gen<F: Fn(Self::Output) -> Option<T>, T>(
153        self,
154        filter_map: F,
155    ) -> FilterMapGenerator<Self, F> {
156        FilterMapGenerator {
157            generator: self,
158            filter_map,
159        }
160    }
161
162    /// Traces generated values to `stderr`
163    #[cfg(feature = "std")]
164    #[inline]
165    fn trace(self) -> trace::Trace<Self> {
166        trace::Trace::new(self)
167    }
168}
169
170impl<T: ValueGenerator> ValueGenerator for &T {
171    type Output = T::Output;
172
173    #[inline]
174    fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output> {
175        (*self).generate(driver)
176    }
177
178    #[inline]
179    fn mutate<D: Driver>(&self, driver: &mut D, value: &mut Self::Output) -> Option<()> {
180        (*self).mutate(driver, value)
181    }
182
183    #[inline]
184    fn driver_cache<D: Driver>(&self, driver: &mut D, value: Self::Output) {
185        (*self).driver_cache(driver, value)
186    }
187}
188
189/// Convert a type generator into the default value generator
190pub trait TypeGeneratorWithParams {
191    type Output: ValueGenerator;
192
193    fn gen_with() -> Self::Output;
194}
195
196/// Non-parameterized ValueGenerator given a TypeGenerator
197#[derive(Debug)]
198pub struct TypeValueGenerator<T: TypeGenerator>(PhantomData<T>);
199
200// this needs to be implemented manually so it doesn't force `T: Copy`
201impl<T: TypeGenerator> Copy for TypeValueGenerator<T> {}
202
203impl<T: TypeGenerator> Clone for TypeValueGenerator<T> {
204    fn clone(&self) -> Self {
205        *self
206    }
207}
208
209impl<T: TypeGenerator> Default for TypeValueGenerator<T> {
210    fn default() -> Self {
211        Self(PhantomData)
212    }
213}
214
215impl<T: TypeGenerator + TypeGeneratorWithParams> TypeValueGenerator<T> {
216    pub fn with(self) -> <T as TypeGeneratorWithParams>::Output {
217        T::gen_with()
218    }
219}
220
221impl<T: TypeGenerator> ValueGenerator for TypeValueGenerator<T> {
222    type Output = T;
223
224    #[inline(always)]
225    fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output> {
226        T::generate(driver)
227    }
228
229    #[inline(always)]
230    fn mutate<D: Driver>(&self, driver: &mut D, value: &mut T) -> Option<()> {
231        T::mutate(value, driver)
232    }
233
234    #[inline(always)]
235    fn driver_cache<D: Driver>(&self, driver: &mut D, value: T) {
236        T::driver_cache(value, driver)
237    }
238}
239
240/// Generate a value for a given type
241#[inline]
242pub fn produce<T: TypeGenerator>() -> TypeValueGenerator<T> {
243    TypeValueGenerator(PhantomData)
244}
245
246/// Generate a value for a given type
247#[deprecated = "Use `produce` instead (`gen` conflicts with edition2024)"]
248#[inline]
249pub fn gen<T: TypeGenerator>() -> TypeValueGenerator<T> {
250    TypeValueGenerator(PhantomData)
251}
252
253/// Generate a value for a given type with additional constraints
254#[inline]
255pub fn produce_with<T: TypeGeneratorWithParams>() -> T::Output {
256    T::gen_with()
257}
258
259/// Generate a value for a given type
260#[deprecated = "Use `produce_with` instead (`gen_with` conflicts with edition2024)"]
261#[inline]
262pub fn gen_with<T: TypeGeneratorWithParams>() -> T::Output {
263    produce_with::<T>()
264}
265
266pub use one_of::{one_of, one_value_of};
267
268impl<T: 'static> ValueGenerator for PhantomData<T> {
269    type Output = Self;
270
271    fn generate<D: Driver>(&self, _driver: &mut D) -> Option<Self::Output> {
272        Some(PhantomData)
273    }
274}
275
276impl<T: 'static> TypeGenerator for PhantomData<T> {
277    fn generate<D: Driver>(_driver: &mut D) -> Option<Self> {
278        Some(PhantomData)
279    }
280}
281
282pub struct Constant<T> {
283    value: T,
284}
285
286impl<T: 'static + Clone> ValueGenerator for Constant<T> {
287    type Output = T;
288
289    fn generate<D: Driver>(&self, _driver: &mut D) -> Option<Self::Output> {
290        Some(self.value.clone())
291    }
292}
293
294/// Always generate the same value
295#[inline]
296pub fn constant<T: Clone>(value: T) -> Constant<T> {
297    Constant { value }
298}