1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
use crate::{
    generate::{Generate, State},
    shrink::Shrink,
};

#[derive(Clone, Debug, Default)]
pub struct Filter<I: ?Sized, F = fn(&<I as Generate>::Item) -> bool> {
    filter: F,
    iterations: usize,
    inner: I,
}

impl<G: Generate, F: Fn(&G::Item) -> bool> Filter<G, F> {
    pub const fn new(generate: G, filter: F, iterations: usize) -> Self {
        Self {
            inner: generate,
            filter,
            iterations,
        }
    }
}

impl<G: Generate + ?Sized, F: Fn(&G::Item) -> bool + Clone> Generate for Filter<G, F> {
    type Item = Option<G::Item>;
    type Shrink = Option<G::Shrink>;

    fn generate(&self, state: &mut State) -> Self::Shrink {
        for _ in 0..self.iterations {
            let shrink = self.inner.generate(state);
            let item = shrink.item();
            if (self.filter)(&item) {
                return Some(shrink);
            }
        }
        None
    }
}