1use crate::{
2 generate::{self, Generate, State},
3 shrink::Shrink,
4};
5
6#[derive(Clone, Debug)]
7pub struct Filter<G: ?Sized, F> {
8 pub(crate) filter: F,
9 pub(crate) retries: usize,
10 pub(crate) generator: G,
11}
12
13#[derive(Clone, Debug)]
14pub struct Shrinker<S, F> {
15 shrinker: Option<S>,
16 filter: F,
17}
18
19impl<G: Generate + ?Sized, F: Fn(&G::Item) -> bool + Clone> Generate for Filter<G, F> {
20 type Item = Option<G::Item>;
21 type Shrink = Shrinker<G::Shrink, F>;
22
23 fn generate(&self, state: &mut State) -> Self::Shrink {
24 let mut outer = None;
25 let size = state.size;
26 for i in 0..=self.retries {
27 state.size = generate::size(i, self.retries, size);
28 let inner = self.generator.generate(state);
29 let item = inner.item();
30 if (self.filter)(&item) {
31 outer = Some(inner);
32 break;
33 } else if self.constant() {
34 break;
35 }
36 }
37 state.size = size;
38 Shrinker {
39 shrinker: outer,
40 filter: self.filter.clone(),
41 }
42 }
43
44 fn constant(&self) -> bool {
45 self.generator.constant()
46 }
47}
48
49impl<S: Shrink, F: Fn(&S::Item) -> bool + Clone> Shrink for Shrinker<S, F> {
50 type Item = Option<S::Item>;
51
52 fn item(&self) -> Self::Item {
53 let item = self.shrinker.as_ref()?.item();
54 if (self.filter)(&item) {
55 Some(item)
56 } else {
57 None
58 }
59 }
60
61 fn shrink(&mut self) -> Option<Self> {
62 Some(Shrinker {
63 filter: self.filter.clone(),
64 shrinker: Some(self.shrinker.as_mut()?.shrink()?),
65 })
66 }
67}