Skip to main content

checkito/
filter_map.rs

1use crate::{generate::Generate, shrink::Shrink, state::State};
2
3#[derive(Debug, Clone)]
4pub struct FilterMap<G: ?Sized, F> {
5    pub(crate) filter: F,
6    pub(crate) generator: G,
7}
8
9#[derive(Debug, Clone)]
10pub struct Shrinker<S, F> {
11    shrinker: S,
12    filter: F,
13}
14
15impl<G: Generate + ?Sized, T, F: Fn(G::Item) -> Option<T> + Clone> Generate for FilterMap<G, F> {
16    type Item = Option<T>;
17    type Shrink = Shrinker<G::Shrink, F>;
18
19    const CARDINALITY: Option<u128> = G::CARDINALITY;
20
21    fn generate(&self, state: &mut State) -> Self::Shrink {
22        Shrinker {
23            shrinker: self.generator.generate(state),
24            filter: self.filter.clone(),
25        }
26    }
27
28    fn cardinality(&self) -> Option<u128> {
29        self.generator.cardinality()
30    }
31}
32
33impl<S: Shrink, T, F: Fn(S::Item) -> Option<T> + Clone> Shrink for Shrinker<S, F> {
34    type Item = Option<T>;
35
36    fn item(&self) -> Self::Item {
37        (self.filter)(self.shrinker.item())
38    }
39
40    fn shrink(&mut self) -> Option<Self> {
41        Some(Self {
42            shrinker: self.shrinker.shrink()?,
43            filter: self.filter.clone(),
44        })
45    }
46}