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}