Skip to main content

checkito/
prelude.rs

1use crate::{
2    any::Any,
3    array::Array,
4    boxed::Boxed,
5    cardinality::Cardinality,
6    collect::{Collect, Count},
7    convert::Convert,
8    dampen::Dampen,
9    filter::Filter,
10    filter_map::FilterMap,
11    flatten::Flatten,
12    generate::Generate,
13    keep::Keep,
14    lazy::Lazy,
15    map::Map,
16    primitive::Number,
17    same::Same,
18    shrink::Shrinker,
19    size::Size,
20    standard::{character, number, with},
21    state::Sizes,
22    unify::Unify,
23};
24use core::marker::PhantomData;
25
26/// Creates a generator that always produces the same value.
27///
28/// This is useful for creating parameterized unit tests or for fixing one
29/// input to a test while letting others be generated randomly.
30#[inline]
31pub const fn same<T: Clone>(value: T) -> Same<T> {
32    Same(value)
33}
34
35/// Creates a generator that randomly chooses one of a set of generators.
36///
37/// See [`any`](crate::any()).
38#[inline]
39pub const fn any<G>(generators: G) -> Any<G> {
40    Any(generators)
41}
42
43/// Unifies a generator of a `orn::Or` type into a single type.
44///
45/// See [`unify`](crate::unify()).
46#[inline]
47pub const fn unify<G: Generate, T>(generator: G) -> Unify<G, T> {
48    Unify(PhantomData, generator)
49}
50
51/// Creates a generator that yields the [`Generate::Shrink`] instances instead
52/// of [`Generate::Item`].
53#[inline]
54pub const fn shrinker<G: Generate>(generator: G) -> Shrinker<G> {
55    Shrinker(generator)
56}
57
58/// See [`Generate::map`].
59#[inline]
60pub const fn map<G: Generate, T, F: Fn(G::Item) -> T + Clone>(generator: G, map: F) -> Map<G, F> {
61    Map(map, generator)
62}
63
64/// See [`Generate::flat_map`].
65#[inline]
66pub const fn flat_map<G: Generate, T: Generate, F: Fn(G::Item) -> T + Clone>(
67    generator: G,
68    map: F,
69) -> Flatten<Map<G, F>> {
70    flatten(self::map(generator, map))
71}
72
73/// See [`Generate::flatten`].
74#[inline]
75pub const fn flatten<G: Generate>(generator: G) -> Flatten<G>
76where
77    G::Item: Generate,
78{
79    Flatten(generator)
80}
81
82/// See [`Generate::filter`].
83#[inline]
84pub const fn filter<G: Generate, F: Fn(&G::Item) -> bool + Clone>(
85    generator: G,
86    filter: F,
87) -> Filter<G, F> {
88    Filter { generator, filter }
89}
90
91/// See [`Generate::filter_map`].
92#[inline]
93pub const fn filter_map<G: Generate, T, F: Fn(G::Item) -> Option<T> + Clone>(
94    generator: G,
95    filter: F,
96) -> FilterMap<G, F> {
97    FilterMap { generator, filter }
98}
99
100/// See [`Generate::boxed`].
101#[inline]
102pub const fn boxed<G: Generate + 'static>(generator: Box<G>) -> Boxed<G::Item> {
103    Boxed::new(generator)
104}
105
106/// See [`Generate::array`].
107#[inline]
108pub const fn array<G: Generate, const N: usize>(generator: G) -> Array<G, N> {
109    Array(generator)
110}
111
112/// See [`Generate::collect`].
113#[inline]
114pub const fn collect<G: Generate, C: Count, F: FromIterator<G::Item>>(
115    generator: G,
116    count: C,
117) -> Collect<G, C, F> {
118    Collect {
119        _marker: PhantomData,
120        count,
121        generator,
122    }
123}
124
125/// See [`Generate::size`].
126#[inline]
127pub const fn size<G: Generate, S: Into<Sizes>, F: Fn(Sizes) -> S>(
128    generator: G,
129    map: F,
130) -> Size<G, F> {
131    Size(generator, map)
132}
133
134/// See [`Generate::dampen`] and [`Generate::dampen_with`].
135#[inline]
136pub const fn dampen<G: Generate>(
137    generator: G,
138    pressure: f64,
139    deepest: usize,
140    limit: usize,
141) -> Dampen<G> {
142    Dampen::new(pressure, deepest, limit, generator)
143}
144
145/// See [`Generate::keep`].
146#[inline]
147pub const fn keep<G: Generate>(generator: G) -> Keep<G> {
148    Keep(generator)
149}
150
151/// See [`Generate::convert`].
152#[inline]
153pub const fn convert<G: Generate, T: From<G::Item>>(generator: G) -> Convert<G, T> {
154    Convert(PhantomData, generator)
155}
156
157/// Creates a generator from a regular expression at runtime.
158///
159/// If the regular expression parsing fails, an [`Err`] is returned. For
160/// compile-time checked regexes, see the [`regex!`](crate::regex!) macro.
161#[cfg(feature = "regex")]
162#[inline]
163pub fn regex(
164    pattern: &str,
165    repeats: Option<u32>,
166) -> Result<crate::regex::Regex, crate::regex::Error> {
167    crate::regex::Regex::new(pattern, repeats)
168}
169
170/// A generator for the full range of any [`Number`] type.
171///
172/// This is equivalent to `T::MIN..=T::MAX`.
173#[inline]
174pub const fn number<T: Number>() -> number::Number<T> {
175    number::Number(PhantomData)
176}
177
178/// A generator for any non-negative [`Number`] type (includes `0`).
179///
180/// This is equivalent to `0..=T::MAX`.
181#[inline]
182pub const fn positive<T: Number>() -> number::Positive<T> {
183    number::Positive(PhantomData)
184}
185
186/// A generator for any non-positive [`Number`] type (includes `0`).
187///
188/// This is equivalent to `T::MIN..=0`.
189#[inline]
190pub const fn negative<T: Number>() -> number::Negative<T> {
191    number::Negative(PhantomData)
192}
193
194/// A generator for ASCII letters (`a-z`, `A-Z`).
195#[inline]
196pub const fn letter() -> character::Letter {
197    character::Letter(PhantomData)
198}
199
200/// A generator for ASCII digits (`0-9`).
201#[inline]
202pub const fn digit() -> character::Digit {
203    character::Digit(PhantomData)
204}
205
206/// A generator for all ASCII characters (0-127).
207#[inline]
208pub const fn ascii() -> character::Ascii {
209    character::Ascii(PhantomData)
210}
211
212/// Creates a generator from a closure that produces a value.
213///
214/// **This generator assumes that the closure always returns the same
215/// value; if this assumption is violated, `check`ing and `shrink`ing may have
216/// unexpected behaviors.**
217///
218/// # Examples
219/// ```
220/// # use checkito::*;
221/// struct MyStruct(i32);
222///
223/// // A generator that always produces `MyStruct(42)`.
224/// let generator = with(|| MyStruct(42));
225/// ```
226#[inline]
227pub const fn with<T, F: Fn() -> T + Clone>(generate: F) -> with::With<F> {
228    with::With::new(generate)
229}
230
231/// Defers the construction of a generator until it is used.
232///
233/// This is essential for creating recursive generators. See [`Lazy`] for
234/// details.
235#[inline]
236pub const fn lazy<G: Generate, F: Fn() -> G>(generator: F) -> Lazy<G, F> {
237    Lazy::new(generator)
238}
239
240/// Overrides both the static and dynamic cardinalities of a generator.
241///
242/// This is used when the context allows for a more precise cardinality than the
243/// default estimate.
244///
245/// Providing an incorrect cardinality can cause unexpected behavior when
246/// running [`crate::Check::check`].
247#[inline]
248pub const fn cardinality<G: Generate, const C: u128>(generator: G) -> Cardinality<G, C> {
249    Cardinality(generator)
250}