bolero_generator/
num.rs

1use crate::{
2    bounded::{BoundExt, BoundedGenerator, BoundedValue},
3    Driver, TypeGenerator, TypeGeneratorWithParams, ValueGenerator,
4};
5use core::ops::{Bound, RangeFrom, RangeFull};
6
7macro_rules! impl_integer {
8    ($ty:ident, $call:ident, $constant:ident) => {
9        impl TypeGenerator for $ty {
10            fn generate<D: Driver>(driver: &mut D) -> Option<Self> {
11                driver.$call(Bound::Unbounded, Bound::Unbounded)
12            }
13        }
14
15        impl ValueGenerator for $ty {
16            type Output = $ty;
17
18            fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self> {
19                driver.$constant(*self)
20            }
21        }
22
23        impl BoundedValue for $ty {
24            fn gen_bounded<D: Driver>(
25                driver: &mut D,
26                min: Bound<&Self>,
27                max: Bound<&Self>,
28            ) -> Option<Self> {
29                driver.$call(min, max)
30            }
31        }
32
33        impl TypeGeneratorWithParams for $ty {
34            type Output = BoundedGenerator<Self, RangeFull>;
35
36            fn gen_with() -> Self::Output {
37                BoundedGenerator::new(..)
38            }
39        }
40    };
41}
42
43impl_integer!(u8, gen_u8, gen_u8_constant);
44impl_integer!(i8, gen_i8, gen_i8_constant);
45impl_integer!(u16, gen_u16, gen_u16_constant);
46impl_integer!(i16, gen_i16, gen_i16_constant);
47impl_integer!(u32, gen_u32, gen_u32_constant);
48impl_integer!(i32, gen_i32, gen_i32_constant);
49impl_integer!(u64, gen_u64, gen_u64_constant);
50impl_integer!(i64, gen_i64, gen_i64_constant);
51impl_integer!(u128, gen_u128, gen_u128_constant);
52impl_integer!(i128, gen_i128, gen_i128_constant);
53impl_integer!(usize, gen_usize, gen_usize_constant);
54impl_integer!(isize, gen_isize, gen_isize_constant);
55
56#[test]
57fn integer_test() {
58    let _ = generator_test!(produce::<u8>());
59    let _ = generator_test!(produce::<i8>());
60    let _ = generator_test!(produce::<u16>());
61    let _ = generator_test!(produce::<i16>());
62    let _ = generator_test!(produce::<u32>());
63    let _ = generator_test!(produce::<i32>());
64    let _ = generator_test!(produce::<u64>());
65    let _ = generator_test!(produce::<i64>());
66    let _ = generator_test!(produce::<u128>());
67    let _ = generator_test!(produce::<i128>());
68    let _ = generator_test!(produce::<usize>());
69    let _ = generator_test!(produce::<isize>());
70}
71
72macro_rules! impl_float {
73    ($ty:ident, $call:ident, $constant:ident) => {
74        impl TypeGenerator for $ty {
75            fn generate<D: Driver>(driver: &mut D) -> Option<Self> {
76                driver.$call(Bound::Unbounded, Bound::Unbounded)
77            }
78        }
79
80        impl ValueGenerator for $ty {
81            type Output = $ty;
82
83            fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self> {
84                driver.$constant(*self)
85            }
86        }
87
88        impl BoundedValue for $ty {
89            fn gen_bounded<D: Driver>(
90                driver: &mut D,
91                min: Bound<&Self>,
92                max: Bound<&Self>,
93            ) -> Option<Self> {
94                driver.$call(min, max)
95            }
96        }
97
98        impl TypeGeneratorWithParams for $ty {
99            type Output = BoundedGenerator<Self, RangeFull>;
100
101            fn gen_with() -> Self::Output {
102                BoundedGenerator::new(..)
103            }
104        }
105    };
106}
107
108impl_float!(f32, gen_f32, gen_f32_constant);
109impl_float!(f64, gen_f64, gen_f64_constant);
110
111#[test]
112fn float_test() {
113    // TODO filter NaN for mutation comparison
114    //let _ = generator_test!(gen::<f32>());
115    //let _ = generator_test!(gen::<f64>());
116}
117
118macro_rules! impl_non_zero_integer {
119    ($ty:ident, $inner:ty) => {
120        impl TypeGenerator for core::num::$ty {
121            fn generate<D: Driver>(driver: &mut D) -> Option<Self> {
122                let value = (1..).generate(driver)?;
123                Self::new(value)
124            }
125        }
126
127        impl BoundedValue for core::num::$ty {
128            fn gen_bounded<D: Driver>(
129                driver: &mut D,
130                min: Bound<&Self>,
131                max: Bound<&Self>,
132            ) -> Option<Self> {
133                let min = BoundExt::map(min, |value| value.get());
134                let max = BoundExt::map(max, |value| value.get());
135
136                let value = BoundedValue::gen_bounded(
137                    driver,
138                    BoundExt::as_ref(&min),
139                    BoundExt::as_ref(&max),
140                )?;
141                Self::new(value)
142            }
143        }
144
145        impl BoundedValue<$inner> for core::num::$ty {
146            fn gen_bounded<D: Driver>(
147                driver: &mut D,
148                min: Bound<&$inner>,
149                max: Bound<&$inner>,
150            ) -> Option<Self> {
151                let value = BoundedValue::gen_bounded(driver, min, max)?;
152                Self::new(value)
153            }
154        }
155
156        impl TypeGeneratorWithParams for core::num::$ty {
157            type Output = BoundedGenerator<Self, RangeFrom<Self>>;
158
159            fn gen_with() -> Self::Output {
160                BoundedGenerator::new(unsafe { core::num::$ty::new_unchecked(1) }..)
161            }
162        }
163    };
164}
165
166impl_non_zero_integer!(NonZeroI8, i8);
167impl_non_zero_integer!(NonZeroU8, u8);
168impl_non_zero_integer!(NonZeroI16, i16);
169impl_non_zero_integer!(NonZeroU16, u16);
170impl_non_zero_integer!(NonZeroI32, i32);
171impl_non_zero_integer!(NonZeroU32, u32);
172impl_non_zero_integer!(NonZeroI64, i64);
173impl_non_zero_integer!(NonZeroU64, u64);
174impl_non_zero_integer!(NonZeroI128, i128);
175impl_non_zero_integer!(NonZeroU128, u128);
176impl_non_zero_integer!(NonZeroIsize, isize);
177impl_non_zero_integer!(NonZeroUsize, usize);