hegel/generators/
default.rs1use crate::generators::binary;
2
3use super::{
4 BoolGenerator, BoxedGenerator, CharactersGenerator, DurationGenerator, FloatGenerator,
5 Generator, HashMapGenerator, HashSetGenerator, IntegerGenerator, IpAddressGenerator,
6 Ipv4AddressGenerator, Ipv6AddressGenerator, OptionalGenerator, TextGenerator, VecGenerator,
7 booleans, characters, collections::ArrayGenerator, durations, floats, hashmaps, hashsets,
8 integers, ip_addresses, optional, text, vecs,
9};
10use std::collections::{HashMap, HashSet};
11use std::hash::Hash;
12use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
13use std::path::PathBuf;
14use std::time::Duration;
15
16pub trait DefaultGenerator: Sized {
20 type Generator: super::Generator<Self> + 'static;
21 fn default_generator() -> Self::Generator;
22}
23
24pub fn default<T: DefaultGenerator>() -> T::Generator {
52 T::default_generator()
53}
54
55impl DefaultGenerator for bool {
56 type Generator = BoolGenerator;
57 fn default_generator() -> Self::Generator {
58 booleans()
59 }
60}
61
62impl DefaultGenerator for String {
63 type Generator = TextGenerator;
64 fn default_generator() -> Self::Generator {
65 text()
66 }
67}
68
69impl DefaultGenerator for char {
70 type Generator = CharactersGenerator;
71 fn default_generator() -> Self::Generator {
72 characters()
73 }
74}
75
76impl DefaultGenerator for i8 {
77 type Generator = IntegerGenerator<i8>;
78 fn default_generator() -> Self::Generator {
79 integers()
80 }
81}
82
83impl DefaultGenerator for i16 {
84 type Generator = IntegerGenerator<i16>;
85 fn default_generator() -> Self::Generator {
86 integers()
87 }
88}
89
90impl DefaultGenerator for i32 {
91 type Generator = IntegerGenerator<i32>;
92 fn default_generator() -> Self::Generator {
93 integers()
94 }
95}
96
97impl DefaultGenerator for i64 {
98 type Generator = IntegerGenerator<i64>;
99 fn default_generator() -> Self::Generator {
100 integers()
101 }
102}
103
104impl DefaultGenerator for u8 {
105 type Generator = IntegerGenerator<u8>;
106 fn default_generator() -> Self::Generator {
107 integers()
108 }
109}
110
111impl DefaultGenerator for u16 {
112 type Generator = IntegerGenerator<u16>;
113 fn default_generator() -> Self::Generator {
114 integers()
115 }
116}
117
118impl DefaultGenerator for u32 {
119 type Generator = IntegerGenerator<u32>;
120 fn default_generator() -> Self::Generator {
121 integers()
122 }
123}
124
125impl DefaultGenerator for u64 {
126 type Generator = IntegerGenerator<u64>;
127 fn default_generator() -> Self::Generator {
128 integers()
129 }
130}
131
132impl DefaultGenerator for i128 {
133 type Generator = IntegerGenerator<i128>;
134 fn default_generator() -> Self::Generator {
135 integers()
136 }
137}
138
139impl DefaultGenerator for u128 {
140 type Generator = IntegerGenerator<u128>;
141 fn default_generator() -> Self::Generator {
142 integers()
143 }
144}
145
146impl DefaultGenerator for isize {
147 type Generator = IntegerGenerator<isize>;
148 fn default_generator() -> Self::Generator {
149 integers()
150 }
151}
152
153impl DefaultGenerator for usize {
154 type Generator = IntegerGenerator<usize>;
155 fn default_generator() -> Self::Generator {
156 integers()
157 }
158}
159
160impl DefaultGenerator for f32 {
161 type Generator = FloatGenerator<f32>;
162 fn default_generator() -> Self::Generator {
163 floats()
164 }
165}
166
167impl DefaultGenerator for f64 {
168 type Generator = FloatGenerator<f64>;
169 fn default_generator() -> Self::Generator {
170 floats()
171 }
172}
173
174impl<T: DefaultGenerator + 'static> DefaultGenerator for Option<T>
175where
176 T::Generator: Send + Sync,
177{
178 type Generator = OptionalGenerator<T::Generator, T>;
179 fn default_generator() -> Self::Generator {
180 optional(T::default_generator())
181 }
182}
183
184impl<T: DefaultGenerator + 'static> DefaultGenerator for Vec<T>
185where
186 T::Generator: Send + Sync,
187{
188 type Generator = VecGenerator<T::Generator, T>;
189 fn default_generator() -> Self::Generator {
190 vecs(T::default_generator())
191 }
192}
193
194impl<T: DefaultGenerator + 'static, const N: usize> DefaultGenerator for [T; N]
195where
196 T::Generator: Send + Sync,
197{
198 type Generator = ArrayGenerator<T::Generator, T, N>;
199 fn default_generator() -> Self::Generator {
200 ArrayGenerator::new(T::default_generator())
201 }
202}
203
204impl DefaultGenerator for Duration {
205 type Generator = DurationGenerator;
206 fn default_generator() -> Self::Generator {
207 durations()
208 }
209}
210
211impl DefaultGenerator for PathBuf {
212 type Generator = BoxedGenerator<'static, PathBuf>;
213 fn default_generator() -> Self::Generator {
214 #[cfg(unix)]
215 {
216 use std::os::unix::ffi::OsStringExt;
217 binary()
218 .map(std::ffi::OsString::from_vec)
219 .map(PathBuf::from)
220 .boxed()
221 }
222 #[cfg(windows)]
223 {
224 use std::os::windows::ffi::OsStringExt;
225 vecs(integers())
226 .map(|wide: Vec<u16>| std::ffi::OsString::from_wide(&wide))
227 .map(PathBuf::from)
228 .boxed()
229 }
230 #[cfg(not(any(unix, windows)))]
231 {
232 text().map(PathBuf::from).boxed()
233 }
234 }
235}
236
237impl DefaultGenerator for IpAddr {
238 type Generator = IpAddressGenerator;
239
240 fn default_generator() -> Self::Generator {
241 ip_addresses()
242 }
243}
244
245impl DefaultGenerator for Ipv4Addr {
246 type Generator = Ipv4AddressGenerator;
247
248 fn default_generator() -> Self::Generator {
249 ip_addresses().v4()
250 }
251}
252
253impl DefaultGenerator for Ipv6Addr {
254 type Generator = Ipv6AddressGenerator;
255
256 fn default_generator() -> Self::Generator {
257 ip_addresses().v6()
258 }
259}
260
261impl<K: DefaultGenerator + 'static, V: DefaultGenerator + 'static> DefaultGenerator
262 for HashMap<K, V>
263where
264 K: Eq + Hash,
265 K::Generator: Send + Sync,
266 V::Generator: Send + Sync,
267{
268 type Generator = HashMapGenerator<K::Generator, V::Generator, K, V>;
269 fn default_generator() -> Self::Generator {
270 hashmaps(K::default_generator(), V::default_generator())
271 }
272}
273
274impl<T: DefaultGenerator + 'static> DefaultGenerator for HashSet<T>
275where
276 T: Eq + Hash,
277 T::Generator: Send + Sync,
278{
279 type Generator = HashSetGenerator<T::Generator, T>;
280 fn default_generator() -> Self::Generator {
281 hashsets(T::default_generator())
282 }
283}
284
285#[macro_export]
318macro_rules! derive_generator {
319 ($struct_name:ident { $($field_name:ident : $field_type:ty),* $(,)? }) => {
320 const _: () = {
321 $crate::paste::paste! {
322 pub struct [<$struct_name Generator>]<'a> {
323 $(
324 $field_name: $crate::generators::BoxedGenerator<'a, $field_type>,
325 )*
326 }
327
328 impl<'a> [<$struct_name Generator>]<'a> {
329 pub fn new() -> Self
330 where
331 $($field_type: $crate::generators::DefaultGenerator,)*
332 $(<$field_type as $crate::generators::DefaultGenerator>::Generator: Send + Sync + 'a,)*
333 {
334 use $crate::generators::{DefaultGenerator, Generator};
335 Self {
336 $($field_name: <$field_type as DefaultGenerator>::default_generator().boxed(),)*
337 }
338 }
339
340 $(
341 pub fn $field_name<G>(mut self, generator: G) -> Self
342 where
343 G: $crate::generators::Generator<$field_type> + Send + Sync + 'a,
344 {
345 use $crate::generators::Generator;
346 self.$field_name = generator.boxed();
347 self
348 }
349 )*
350 }
351
352 impl<'a> Default for [<$struct_name Generator>]<'a>
353 where
354 $($field_type: $crate::generators::DefaultGenerator,)*
355 $(<$field_type as $crate::generators::DefaultGenerator>::Generator: Send + Sync + 'a,)*
356 {
357 fn default() -> Self {
358 Self::new()
359 }
360 }
361
362 impl<'a> $crate::generators::Generator<$struct_name> for [<$struct_name Generator>]<'a> {
363 fn do_draw(&self, __tc: &$crate::TestCase) -> $struct_name {
364 use $crate::generators::Generator;
365 $struct_name {
366 $($field_name: self.$field_name.do_draw(__tc),)*
367 }
368 }
369 }
370
371 impl $crate::generators::DefaultGenerator for $struct_name
372 where
373 $($field_type: $crate::generators::DefaultGenerator,)*
374 $(<$field_type as $crate::generators::DefaultGenerator>::Generator: Send + Sync + 'static,)*
375 {
376 type Generator = [<$struct_name Generator>]<'static>;
377 fn default_generator() -> Self::Generator {
378 [<$struct_name Generator>]::new()
379 }
380 }
381 }
382 };
383 };
384}