bolero_generator/
combinator.rs

1use crate::{Driver, ValueGenerator};
2
3#[derive(Clone, Debug)]
4pub struct MapGenerator<Generator, Map> {
5    pub(crate) generator: Generator,
6    pub(crate) map: Map,
7}
8
9impl<G: ValueGenerator, M: Fn(G::Output) -> T, T: 'static> ValueGenerator for MapGenerator<G, M> {
10    type Output = T;
11
12    fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output> {
13        driver.enter_combinator::<Self::Output, _, _>(|driver| {
14            let value = self.generator.generate(driver)?;
15            Some((self.map)(value))
16        })
17    }
18}
19
20#[test]
21fn map_test() {
22    let _ = generator_test!(produce::<u8>().map_gen(|value| value > 4));
23}
24
25#[derive(Clone, Debug)]
26pub struct AndThenGenerator<Generator, AndThen> {
27    pub(crate) generator: Generator,
28    pub(crate) and_then: AndThen,
29}
30
31impl<G: ValueGenerator, H: ValueGenerator, F: Fn(G::Output) -> H> ValueGenerator
32    for AndThenGenerator<G, F>
33{
34    type Output = H::Output;
35
36    fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output> {
37        driver.enter_combinator::<Self::Output, _, _>(|driver| {
38            driver.enter_product::<Self::Output, _, _>(|driver| {
39                let value = self.generator.generate(driver)?;
40                (self.and_then)(value).generate(driver)
41            })
42        })
43    }
44}
45
46#[test]
47fn and_then_test() {
48    let _ = generator_test!(produce::<u8>().and_then_gen(|value| value..));
49}
50
51#[derive(Clone, Debug)]
52pub struct FilterGenerator<Generator, Filter> {
53    pub(crate) generator: Generator,
54    pub(crate) filter: Filter,
55}
56
57impl<G: ValueGenerator, F: Fn(&G::Output) -> bool> ValueGenerator for FilterGenerator<G, F> {
58    type Output = G::Output;
59
60    fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output> {
61        driver.enter_combinator::<Self::Output, _, _>(|driver| {
62            let value = self.generator.generate(driver)?;
63            if (self.filter)(&value) {
64                Some(value)
65            } else {
66                None
67            }
68        })
69    }
70}
71
72#[test]
73fn filter_test() {
74    let _ = generator_test!(produce::<u8>().filter_gen(|value| *value > 40));
75}
76
77#[derive(Clone, Debug)]
78pub struct FilterMapGenerator<Generator, FilterMap> {
79    pub(crate) generator: Generator,
80    pub(crate) filter_map: FilterMap,
81}
82
83impl<G: ValueGenerator, F: Fn(G::Output) -> Option<T>, T: 'static> ValueGenerator
84    for FilterMapGenerator<G, F>
85{
86    type Output = T;
87
88    fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output> {
89        driver.enter_combinator::<Self::Output, _, _>(|driver| {
90            let value = self.generator.generate(driver)?;
91            (self.filter_map)(value)
92        })
93    }
94}
95
96#[test]
97fn filter_map_test() {
98    let _ = generator_test!(produce::<u8>().filter_map_gen(|value| Some(value > 40)));
99}