use crate::{ generate::{self, Generate, State}, shrink::Shrink, }; #[derive(Clone, Debug)] pub struct Filter { pub(crate) filter: F, pub(crate) retries: usize, pub(crate) generator: G, } #[derive(Clone, Debug)] pub struct Shrinker { shrinker: Option, filter: F, } impl bool + Clone> Generate for Filter { type Item = Option; type Shrink = Shrinker; fn generate(&self, state: &mut State) -> Self::Shrink { let mut outer = None; let size = state.size; for i in 0..=self.retries { state.size = generate::size(i, self.retries, size); let inner = self.generator.generate(state); let item = inner.item(); if (self.filter)(&item) { outer = Some(inner); break; } else if self.constant() { break; } } state.size = size; Shrinker { shrinker: outer, filter: self.filter.clone(), } } fn constant(&self) -> bool { self.generator.constant() } } impl bool + Clone> Shrink for Shrinker { type Item = Option; fn item(&self) -> Self::Item { let item = self.shrinker.as_ref()?.item(); if (self.filter)(&item) { Some(item) } else { None } } fn shrink(&mut self) -> Option { Some(Shrinker { filter: self.filter.clone(), shrinker: Some(self.shrinker.as_mut()?.shrink()?), }) } }