pub trait Generate {
type Item;
type Shrink: Shrink<Item = Self::Item>;
Show 23 methods
// Required method
fn generate(&self, state: &mut State) -> Self::Shrink;
// Provided methods
fn boxed(self) -> Generator<Self::Item>
where Self: Sized + 'static,
Generator<Self::Item>: Generate { ... }
fn map<T, F: Fn(Self::Item) -> T>(self, map: F) -> Map<Self, F>
where Self: Sized,
Map<Self, F>: Generate { ... }
fn filter<F: Fn(&Self::Item) -> bool>(self, filter: F) -> Filter<Self, F>
where Self: Sized,
Filter<Self, F>: Generate { ... }
fn filter_with<F: Fn(&Self::Item) -> bool>(
self,
retries: usize,
filter: F,
) -> Filter<Self, F>
where Self: Sized,
Filter<Self, F>: Generate { ... }
fn filter_map<T, F: Fn(Self::Item) -> Option<T>>(
self,
map: F,
) -> FilterMap<Self, F>
where Self: Sized,
FilterMap<Self, F>: Generate { ... }
fn filter_map_with<T, F: Fn(Self::Item) -> Option<T>>(
self,
retries: usize,
map: F,
) -> FilterMap<Self, F>
where Self: Sized,
FilterMap<Self, F>: Generate { ... }
fn flat_map<G: Generate, F: Fn(Self::Item) -> G>(
self,
map: F,
) -> Flatten<Map<Self, F>>
where Self: Sized,
Map<Self, F>: Generate<Item = G>,
Flatten<Map<Self, F>>: Generate { ... }
fn flatten(self) -> Flatten<Self>
where Self: Sized,
Self::Item: Generate,
Flatten<Self>: Generate { ... }
fn any(self) -> Any<Self>
where Self: Sized,
Any<Self>: Generate { ... }
fn array<const N: usize>(self) -> Array<Self, N>
where Self: Sized,
Array<Self, N>: Generate { ... }
fn collect<F: FromIterator<Self::Item>>(
self,
) -> Collect<Self, Range<usize>, F>
where Self: Sized,
Collect<Self, Range<usize>, F>: Generate { ... }
fn collect_with<C: Generate<Item = usize>, F: FromIterator<Self::Item>>(
self,
count: C,
) -> Collect<Self, C, F>
where Self: Sized,
Collect<Self, C, F>: Generate { ... }
fn size<F: Fn(f64, usize) -> f64>(self, map: F) -> Size<Self, F>
where Self: Sized,
Size<Self, F>: Generate { ... }
fn dampen(self) -> Dampen<Self>
where Self: Sized,
Size<Self>: Generate { ... }
fn dampen_with(
self,
pressure: f64,
deepest: usize,
limit: usize,
) -> Dampen<Self>
where Self: Sized,
Dampen<Self>: Generate { ... }
fn keep(self) -> Keep<Self>
where Self: Sized,
Keep<Self>: Generate { ... }
fn sampler(&self) -> Sampler<'_, Self> { ... }
fn samples(&self, count: usize) -> Samples<'_, Self> ⓘ { ... }
fn sample(&self, size: f64) -> Self::Item { ... }
fn checker(&self) -> Checker<'_, Self> { ... }
fn checks<P: Prove, F: FnMut(&Self::Item) -> P>(
&self,
count: usize,
check: F,
) -> Checks<'_, Self, F> ⓘ { ... }
fn check<P: Prove, F: FnMut(&Self::Item) -> P>(
&self,
count: usize,
check: F,
) -> Result<(), Error<Self::Item, P>> { ... }
}Required Associated Types§
Required Methods§
Provided Methods§
sourcefn boxed(self) -> Generator<Self::Item>
fn boxed(self) -> Generator<Self::Item>
Wraps self in a boxed Generate. This is notably relevant for recursive Generate implementations where
the type would otherwise be infinite.
§Examples
use checkito::*;
enum Node {
Leaf,
Branch(Vec<Node>),
}
fn node() -> impl Generate<Item = Node> {
(
with(|| Node::Leaf),
// Without [`Generate::boxed`], this type would be infinite.
lazy(node).collect().map(Node::Branch).boxed()
)
.any()
.map(|or| or.into())
}
fn choose(choose: bool) -> impl Generate<Item = char> {
if choose {
// Without [`Generate::boxed`], the `if/else` branches would not have the same type.
letter().boxed()
} else {
digit().boxed()
}
}sourcefn map<T, F: Fn(Self::Item) -> T>(self, map: F) -> Map<Self, F>
fn map<T, F: Fn(Self::Item) -> T>(self, map: F) -> Map<Self, F>
Maps generated Generate::Item to an arbitrary type T using the provided function F.
sourcefn filter<F: Fn(&Self::Item) -> bool>(self, filter: F) -> Filter<Self, F>
fn filter<F: Fn(&Self::Item) -> bool>(self, filter: F) -> Filter<Self, F>
Same as Generate::filter_with but with a predefined number of retries.
sourcefn filter_with<F: Fn(&Self::Item) -> bool>(
self,
retries: usize,
filter: F,
) -> Filter<Self, F>
fn filter_with<F: Fn(&Self::Item) -> bool>( self, retries: usize, filter: F, ) -> Filter<Self, F>
Generates many Generate::Item with an increasingly large size until the filter function F is satisfied, up to
the maximum number of retries.
Since this Generate implementation is not guaranteed to succeed, the item type is changed to a Option<Generate::Item>
where a None represents the failure to satisfy the filter.
sourcefn filter_map<T, F: Fn(Self::Item) -> Option<T>>(
self,
map: F,
) -> FilterMap<Self, F>
fn filter_map<T, F: Fn(Self::Item) -> Option<T>>( self, map: F, ) -> FilterMap<Self, F>
Same as Generate::filter_map_with but with a predefined number of retries.
sourcefn filter_map_with<T, F: Fn(Self::Item) -> Option<T>>(
self,
retries: usize,
map: F,
) -> FilterMap<Self, F>
fn filter_map_with<T, F: Fn(Self::Item) -> Option<T>>( self, retries: usize, map: F, ) -> FilterMap<Self, F>
Combines Generate::map and Generate::filter in a single Generate implementation where the map function
is considered to satisfy the filter when a [Some(T)] is produced.
sourcefn flat_map<G: Generate, F: Fn(Self::Item) -> G>(
self,
map: F,
) -> Flatten<Map<Self, F>>
fn flat_map<G: Generate, F: Fn(Self::Item) -> G>( self, map: F, ) -> Flatten<Map<Self, F>>
Combines Generate::map and Generate::flatten in a single Generate implementation.
sourcefn flatten(self) -> Flatten<Self>
fn flatten(self) -> Flatten<Self>
Flattens the Generate::Item, assuming that it implements Generate. The resulting item type is
<Generate::Item as Generate>::Item.
Additionally, the call to Generate::generate to the inner Generate implementation will have its depth
increased by 1. The depth is a value used by other Generate implementations (such as Generate::size and
Generate::dampen) to alter the size of generated items. It tries to represent the recursion depth since it
is expected that recursive Generate instances will need to go through it. Implementations such as lazy
and Generate::flat_map use it.
The depth is particularly useful to limit the amount of recursion that happens for
structures that potentially explode exponentially as the recursion depth increases (think of a tree structure).
sourcefn any(self) -> Any<Self>
fn any(self) -> Any<Self>
For a type T where Any<T> implements Generate, the behavior of the generation changes from generate all of
my components to generate one of my components chosen randomly.
It is implemented for tuples, slices, arrays, Vec<T> and a few other collections.
The random selection can be controlled by wrapping each element of a supported collection in a
any::Weight, which will inform the Generate implementation to perform a weighted random
between elements of the collection.
sourcefn collect<F: FromIterator<Self::Item>>(self) -> Collect<Self, Range<usize>, F>
fn collect<F: FromIterator<Self::Item>>(self) -> Collect<Self, Range<usize>, F>
Same as Generate::collect_with but with a predefined count.
sourcefn collect_with<C: Generate<Item = usize>, F: FromIterator<Self::Item>>(
self,
count: C,
) -> Collect<Self, C, F>
fn collect_with<C: Generate<Item = usize>, F: FromIterator<Self::Item>>( self, count: C, ) -> Collect<Self, C, F>
Generates a variable number of items based on the provided count Generate and then builds a value of type
F based on its implementation of FromIterator.
sourcefn size<F: Fn(f64, usize) -> f64>(self, map: F) -> Size<Self, F>
fn size<F: Fn(f64, usize) -> f64>(self, map: F) -> Size<Self, F>
Maps the current size of the generation process to a different one. The size is a value in the range [0.0..1.0]
that represents how big the generated items are based on the generator’s constraints. The generation process will
initially try to produce small items and then move on to bigger ones.
Note that the size does not guarantee a small or big generated item since Generate implementations are free
to interpret it as they wish, although that is its intention.
For example, a small number will be close to 0, a small collection will have its len() close to 0, a large
bool will be true, a large String will have many char, etc.
The provided map function is described as such:
- Its first argument is the current
sizein the range[0.0..1.0]. - Its second argument is the current
depth(seeGenerate::flattenfor more information aboutdepth). - Its return value will be clamped to the
[0.0..1.0]range and panic if it is infinite orf64::NAN.
Useful to nullify the sizing of items (self.size(|_, _| 1.0) will always produces items of full size) or to
attenuate the size.
sourcefn dampen(self) -> Dampen<Self>
fn dampen(self) -> Dampen<Self>
Same as Generate::dampen_with but with predefined arguments.
sourcefn dampen_with(
self,
pressure: f64,
deepest: usize,
limit: usize,
) -> Dampen<Self>
fn dampen_with( self, pressure: f64, deepest: usize, limit: usize, ) -> Dampen<Self>
Dampens the size (see Generate::size for more information about size) as items are generated.
- The
pressurecan be thought of as how fast will thesizebe reduced as thedepthincreases (seeGenerate::flattenfor more information aboutdepth). - The
deepestwill set thesizeto0when thedepthis>=than it. - The
limitwill set thesizeto0after the number of times that thedepthincreased is>=than it.
This Generate implementation is particularly useful to limit the amount of recursion that happens for structures
that are infinite and potentially explode exponentially as the recursion depth increases (think of a tree structure).
sourcefn keep(self) -> Keep<Self>
fn keep(self) -> Keep<Self>
Keeps the generated items intact through the shrinking process (i.e. un-shrinked).
sourcefn sampler(&self) -> Sampler<'_, Self>
fn sampler(&self) -> Sampler<'_, Self>
Provides a Sampler that allows to configure sampling settings and generate samples.
sourcefn samples(&self, count: usize) -> Samples<'_, Self> ⓘ
fn samples(&self, count: usize) -> Samples<'_, Self> ⓘ
Generates count random values the are progressively larger in size. For additional sampling settings, see Generate::sampler.
sourcefn sample(&self, size: f64) -> Self::Item
fn sample(&self, size: f64) -> Self::Item
Generates a random value of size (0.0..=1.0). For additional sampling settings, see Generate::sampler.