bolero_generator/
range.rs1use crate::{Driver, TypeGenerator, TypeGeneratorWithParams, TypeValueGenerator, ValueGenerator};
2
3macro_rules! range_generator {
4 ($ty:ident, $generator:ident, | $start:ident, $end:ident | $new:expr) => {
5 pub struct $generator<Start, End> {
6 start: Start,
7 end: End,
8 }
9
10 impl<Start, End, T> $generator<Start, End>
11 where
12 Start: ValueGenerator<Output = T>,
13 End: ValueGenerator<Output = T>,
14 {
15 pub fn start<NewS: ValueGenerator<Output = T>>(
16 self,
17 start: NewS,
18 ) -> $generator<NewS, End> {
19 $generator {
20 start,
21 end: self.end,
22 }
23 }
24
25 pub fn map_start<NewS: ValueGenerator<Output = T>, F: Fn(Start) -> NewS>(
26 self,
27 map: F,
28 ) -> $generator<NewS, End> {
29 $generator {
30 start: map(self.start),
31 end: self.end,
32 }
33 }
34
35 pub fn end<NewE: ValueGenerator<Output = T>>(
36 self,
37 end: NewE,
38 ) -> $generator<Start, NewE> {
39 $generator {
40 start: self.start,
41 end,
42 }
43 }
44
45 pub fn map_end<NewE: ValueGenerator<Output = T>, F: Fn(End) -> NewE>(
46 self,
47 map: F,
48 ) -> $generator<Start, NewE> {
49 $generator {
50 start: self.start,
51 end: map(self.end),
52 }
53 }
54 }
55
56 impl<Start, End, T> ValueGenerator for $generator<Start, End>
57 where
58 Start: ValueGenerator<Output = T>,
59 End: ValueGenerator<Output = T>,
60 T: 'static,
61 {
62 type Output = core::ops::$ty<T>;
63
64 fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output> {
65 driver.enter_product::<Self::Output, _, _>(|driver| {
66 let $start = self.start.generate(driver)?;
67 let $end = self.end.generate(driver)?;
68 Some($new)
69 })
70 }
71 }
72
73 impl<T: TypeGenerator> TypeGenerator for core::ops::$ty<T> {
74 fn generate<D: Driver>(driver: &mut D) -> Option<Self> {
75 driver.enter_product::<Self, _, _>(|driver| {
76 let $start = driver.produce()?;
77 let $end = driver.produce()?;
78 Some($new)
79 })
80 }
81 }
82
83 impl<T: TypeGenerator> TypeGeneratorWithParams for core::ops::$ty<T> {
84 type Output = $generator<TypeValueGenerator<T>, TypeValueGenerator<T>>;
85
86 fn gen_with() -> Self::Output {
87 $generator {
88 start: Default::default(),
89 end: Default::default(),
90 }
91 }
92 }
93 };
94}
95
96range_generator!(Range, RangeGenerator, |start, end| start..end);
97range_generator!(RangeInclusive, RangeInclusiveGenerator, |start, end| start
98 ..=end);
99
100#[test]
101fn range_type_test() {
102 use core::ops::Range;
103
104 let _ = generator_test!(produce::<Range<usize>>());
105}
106
107#[test]
108fn range_with_test() {
109 use core::ops::Range;
110
111 let _ = generator_test!(produce::<Range<usize>>().with().start(4..6).end(6..10));
112}
113
114#[test]
115fn range_gen_test() {
116 let _ = generator_test!(0usize..10);
117}