mutatis/mutators/
core_impls.rs

1use super::*;
2use crate::Result;
3use core::{cmp, ops};
4
5mod option;
6mod result;
7pub use option::*;
8pub use result::*;
9
10/// The default mutator for `bool` values.
11///
12/// See the [`bool()`] function to create new instances and for example usage.
13#[derive(Clone, Debug, Default)]
14pub struct Bool {
15    _private: (),
16}
17
18/// Create a new `bool` mutator.
19///
20/// # Example
21///
22/// ```
23/// use mutatis::{mutators as m, Mutate, Session};
24///
25/// let mut mutator = m::bool();
26/// let mut session = Session::new();
27///
28/// let mut value = true;
29/// session.mutate_with(&mut mutator, &mut value).unwrap();
30///
31/// assert_eq!(value, false);
32/// ```
33pub fn bool() -> Bool {
34    Bool { _private: () }
35}
36
37impl Mutate<bool> for Bool {
38    #[inline]
39    fn mutate(&mut self, c: &mut Candidates, value: &mut bool) -> Result<()> {
40        if !c.shrink() || *value {
41            c.mutation(|_ctx| Ok(*value = !*value))?;
42        }
43        Ok(())
44    }
45}
46
47impl DefaultMutate for bool {
48    type DefaultMutate = Bool;
49}
50
51macro_rules! ints {
52    (
53        $(
54            $fn_name:ident -> $ty_name:ident : $method:ident for $ty:ty ;
55        )*
56    ) => {
57        $(
58            /// A mutator for
59            #[doc = concat!("`", stringify!($fn_name), "`")]
60            /// values.
61            ///
62            /// See the
63            #[doc = concat!("[`", stringify!($fn_name), "()`]")]
64            /// function to create new instances and for
65            /// example usage.
66            #[derive(Clone, Debug, Default)]
67            pub struct $ty_name {
68                _private: (),
69            }
70
71            /// Create a new
72            #[doc = concat!("`", stringify!($ty), "`")]
73            /// mutator.
74            ///
75            /// # Example
76            ///
77            /// ```
78            /// use mutatis::{mutators as m, Mutate, Session};
79            ///
80            #[doc = concat!("let mut mutator = m::", stringify!($fn_name), "();")]
81            ///
82            /// let mut session = Session::new().shrink(true);
83            ///
84            /// let mut value = 42;
85            /// session.mutate_with(&mut mutator, &mut value).unwrap();
86            ///
87            /// assert!(value < 42);
88            /// ```
89            pub fn $fn_name() -> $ty_name {
90                $ty_name { _private: () }
91            }
92
93            impl Mutate<$ty> for $ty_name {
94                #[inline]
95                fn mutate(&mut self, c: &mut Candidates, value: &mut $ty) -> Result<()> {
96                    if c.shrink() && *value == 0 {
97                        return Ok(());
98                    }
99                    c.mutation(|ctx| {
100                        *value = if ctx.shrink() {
101                            ctx.rng().inner().gen_range(0..*value)
102                        } else {
103                            ctx.rng().$method()
104                        };
105                        Ok(())
106                    })
107                }
108            }
109
110            impl DefaultMutate for $ty {
111                type DefaultMutate = $ty_name;
112            }
113
114            impl Generate<$ty> for $ty_name {
115                #[inline]
116                fn generate(&mut self, ctx: &mut Context) -> Result<$ty> {
117                    Ok(ctx.rng().$method())
118                }
119            }
120
121            impl MutateInRange<$ty> for $ty_name {
122                #[inline]
123                fn mutate_in_range(
124                    &mut self,
125                    c: &mut Candidates,
126                    value: &mut $ty,
127                    range: &ops::RangeInclusive<$ty>,
128                ) -> Result<()> {
129                    let start = *range.start();
130                    let end = *range.end();
131
132                    if start > end {
133                        return Err(Error::invalid_range());
134                    }
135
136                    if *value == start && c.shrink() {
137                        return Ok(());
138                    }
139
140                    c.mutation(|ctx| {
141                        let end = if ctx.shrink() {
142                            cmp::min(*value, end)
143                        } else {
144                            end
145                        };
146
147                        *value = ctx.rng().inner().gen_range(start..=end);
148                        Ok(())
149                    })
150                }
151            }
152        )*
153    };
154}
155
156ints! {
157    u8 -> U8 : gen_u8 for u8;
158    u16 -> U16 : gen_u16 for u16;
159    u32 -> U32 : gen_u32 for u32;
160    u64 -> U64 : gen_u64 for u64;
161    u128 -> U128 : gen_u128 for u128;
162    usize -> Usize : gen_usize for usize;
163    i8 -> I8 : gen_i8 for i8;
164    i16 -> I16 : gen_i16 for i16;
165    i32 -> I32 : gen_i32 for i32;
166    i64 -> I64 : gen_i64 for i64;
167    i128 -> I128 : gen_i128 for i128;
168    isize -> Isize : gen_isize for isize;
169}
170
171/// A mutator for `char` values.
172///
173/// See the [`char()`] function to create new instances and for example usage.
174#[derive(Clone, Debug, Default)]
175pub struct Char {
176    _private: (),
177}
178
179/// Create a mutator for `char` values.
180///
181/// # Example
182///
183/// ```
184/// # fn foo() -> mutatis::Result<()> {
185/// use mutatis::{mutators as m, Mutate, Session};
186///
187/// let mut mutator = m::char();
188/// let mut session = Session::new();
189///
190/// let mut c = 'a';
191/// for _ in 0..5 {
192///     session.mutate_with(&mut mutator, &mut c)?;
193///     println!("mutated c is {c}");
194/// }
195///
196/// // Example output:
197/// //
198/// //     mutated c is !
199/// //     mutated c is ᐠ
200/// //     mutated c is 𬸚
201/// //     mutated c is 1
202/// //     mutated c is 꼜
203/// # Ok(())
204/// # }
205/// # foo().unwrap();
206/// ```
207pub fn char() -> Char {
208    Char { _private: () }
209}
210
211impl Mutate<char> for Char {
212    #[inline]
213    fn mutate(&mut self, c: &mut Candidates, value: &mut char) -> Result<()> {
214        if c.shrink() {
215            if *value != '\0' {
216                c.mutation(|ctx| {
217                    *value = ctx.rng().inner().gen_range('\0'..*value);
218                    Ok(())
219                })?;
220            }
221            Ok(())
222        } else {
223            // Choose between one of a few different mutation strategies to bias
224            // the distribution towards interesting characters.
225            //
226            // See https://en.wikipedia.org/wiki/Plane_(Unicode)#Overview and
227            // https://en.wikipedia.org/wiki/Unicode_block#List_of_blocks
228            //
229            // Note that the ranges below still contain some unassigned
230            // characters. This is fine. Explicitly listing only assigned
231            // characters is too much work, and this is just a best effort kind
232            // of thing.
233
234            let ch = |x| char::from_u32(x).unwrap_or_else(|| panic!("invalid char: {x:#x}"));
235            let mut char_range = |start, end| range(ch(start)..=ch(end)).mutate(c, value);
236
237            // Non-control ASCII characters.
238            char_range(0x20, 0x7E)?;
239
240            // Plane 0
241            char_range(0x0000, 0xFFFF)?;
242
243            // Plane 1
244            char_range(0x10000, 0x14FFF)?;
245            // Unassigned: 0x15000..=15FFF.
246            char_range(0x16000, 0x18FFF)?;
247            // Unassigned: 0x19000..=1AFFF.
248            char_range(0x1A000, 0x1FFFF)?;
249
250            // Plane 2
251            char_range(0x20000, 0x2FFFF)?;
252
253            // Plane 3
254            char_range(0x30000, 0x32FFF)?;
255
256            // Catch all: any valid character, regardless of its plane, block,
257            // or if it has been assigned or not.
258            c.mutation(|ctx| Ok(*value = ctx.rng().inner().gen()))?;
259
260            Ok(())
261        }
262    }
263}
264
265impl DefaultMutate for char {
266    type DefaultMutate = Char;
267}
268
269impl Generate<char> for Char {
270    #[inline]
271    fn generate(&mut self, ctx: &mut Context) -> Result<char> {
272        Ok(ctx.rng().inner().gen())
273    }
274}
275
276impl MutateInRange<char> for Char {
277    #[inline]
278    fn mutate_in_range(
279        &mut self,
280        c: &mut Candidates,
281        value: &mut char,
282        range: &ops::RangeInclusive<char>,
283    ) -> Result<()> {
284        let start = *range.start();
285        let end = *range.end();
286
287        if start > end {
288            return Err(Error::invalid_range());
289        }
290
291        if *value == start && c.shrink() {
292            return Ok(());
293        }
294
295        c.mutation(|ctx| {
296            let end = if ctx.shrink() {
297                core::cmp::min(*value, end)
298            } else {
299                end
300            };
301            *value = ctx.rng().inner().gen_range(start..=end);
302            Ok(())
303        })
304    }
305}
306
307/// A mutator for `f32` values.
308///
309/// See the [`f32()`] function to create new instances and for example usage.
310pub struct F32 {
311    _private: (),
312}
313
314/// Create a mutator for `f32` values.
315///
316/// # Example
317///
318/// ```
319/// # fn foo() -> mutatis::Result<()> {
320/// use mutatis::{mutators as m, Mutate, Session};
321///
322/// let mut mutator = m::f32();
323/// let mut session = Session::new();
324///
325/// let mut value = 3.14;
326/// for _ in 0..5 {
327///     session.mutate_with(&mut mutator, &mut value)?;
328///     println!("mutated value is {value}");
329/// }
330///
331/// // Example output:
332/// //
333/// //     mutated value is NaN
334/// //     mutated value is -inf
335/// //     mutated value is 0.00000011920929
336/// //     mutated value is -260030670000000000000000000000000000000
337/// //     mutated value is 57951606000000000000000000000000000000
338/// # Ok(())
339/// # }
340/// # foo().unwrap();
341/// ```
342pub fn f32() -> F32 {
343    F32 { _private: () }
344}
345
346impl Mutate<f32> for F32 {
347    #[inline]
348    fn mutate(&mut self, c: &mut Candidates, value: &mut f32) -> Result<()> {
349        let special_finite = |c: &mut Candidates, value: &mut f32| -> Result<()> {
350            c.mutation(|_| Ok(*value = 0.0))?;
351            c.mutation(|_| Ok(*value = 1.0))?;
352            c.mutation(|_| Ok(*value = -1.0))?;
353            c.mutation(|_| Ok(*value = f32::EPSILON))?;
354            c.mutation(|_| Ok(*value = f32::MIN_POSITIVE))?;
355            c.mutation(|_| Ok(*value = f32::MAX))?;
356            c.mutation(|_| Ok(*value = f32::MIN))?;
357            Ok(())
358        };
359
360        let finite = |c: &mut Candidates, value: &mut f32| -> Result<()> {
361            special_finite(c, value)?;
362
363            // Positives.
364            c.mutation(|ctx| Ok(*value = ctx.rng().inner().gen::<f32>() * f32::MAX))?;
365
366            // Negatives.
367            c.mutation(|ctx| Ok(*value = ctx.rng().inner().gen::<f32>() * f32::MIN))?;
368
369            Ok(())
370        };
371
372        if c.shrink() {
373            if *value == 0.0 {
374                return Ok(());
375            }
376            if value.is_nan() || value.is_infinite() {
377                return finite(c, value);
378            }
379            c.mutation(|ctx| Ok(*value *= ctx.rng().inner().gen::<f32>()))?;
380            Ok(())
381        } else {
382            finite(c, value)?;
383            c.mutation(|_| Ok(*value = f32::INFINITY))?;
384            c.mutation(|_| Ok(*value = f32::NEG_INFINITY))?;
385            c.mutation(|_| Ok(*value = f32::NAN))?;
386            Ok(())
387        }
388    }
389}
390
391/// A mutator for `f64` values.
392///
393/// See the [`f64()`] function to create new instances and for example usage.
394pub struct F64 {
395    _private: (),
396}
397
398/// Create a mutator for `f64` values.
399///
400/// # Example
401///
402/// ```
403/// # fn foo() -> mutatis::Result<()> {
404/// use mutatis::{mutators as m, Mutate, Session};
405///
406/// let mut mutator = m::f64();
407/// let mut session = Session::new();
408///
409/// let mut value = 3.14;
410/// for _ in 0..5 {
411///     session.mutate_with(&mut mutator, &mut value)?;
412///     println!("mutated value is {value}");
413/// }
414///
415/// // Example output:
416/// //
417/// //     mutated value is 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072014
418/// //     mutated value is 30615525916172793000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
419/// //     mutated value is -inf
420/// //     mutated value is -179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
421/// //     mutated value is NaN
422/// # Ok(())
423/// # }
424/// # foo().unwrap();
425/// ```
426pub fn f64() -> F64 {
427    F64 { _private: () }
428}
429
430impl Mutate<f64> for F64 {
431    #[inline]
432    fn mutate(&mut self, c: &mut Candidates, value: &mut f64) -> Result<()> {
433        let special_finite = |c: &mut Candidates, value: &mut f64| -> Result<()> {
434            c.mutation(|_| Ok(*value = 0.0))?;
435            c.mutation(|_| Ok(*value = 1.0))?;
436            c.mutation(|_| Ok(*value = -1.0))?;
437            c.mutation(|_| Ok(*value = f64::EPSILON))?;
438            c.mutation(|_| Ok(*value = f64::MIN_POSITIVE))?;
439            c.mutation(|_| Ok(*value = f64::MAX))?;
440            c.mutation(|_| Ok(*value = f64::MIN))?;
441            Ok(())
442        };
443
444        let finite = |c: &mut Candidates, value: &mut f64| -> Result<()> {
445            special_finite(c, value)?;
446
447            // Positives.
448            c.mutation(|ctx| Ok(*value = ctx.rng().inner().gen::<f64>() * f64::MAX))?;
449
450            // Negatives.
451            c.mutation(|ctx| Ok(*value = ctx.rng().inner().gen::<f64>() * f64::MIN))?;
452
453            Ok(())
454        };
455
456        if c.shrink() {
457            if *value == 0.0 {
458                return Ok(());
459            }
460            if value.is_nan() || value.is_infinite() {
461                return finite(c, value);
462            }
463            c.mutation(|ctx| Ok(*value *= ctx.rng().inner().gen::<f64>()))?;
464            Ok(())
465        } else {
466            finite(c, value)?;
467            c.mutation(|_| Ok(*value = f64::INFINITY))?;
468            c.mutation(|_| Ok(*value = f64::NEG_INFINITY))?;
469            c.mutation(|_| Ok(*value = f64::NAN))?;
470            Ok(())
471        }
472    }
473}
474
475// TODO: str
476
477// TODO: slice
478
479macro_rules! tuples {
480    ( $( $fn_name:ident -> $ty_name:ident ( $( $m:ident : $t:ident , )* ) ; )* ) => {
481        $(
482            /// A mutator for tuples.
483            #[derive(Clone, Debug, Default)]
484            #[allow(non_snake_case)]
485            pub struct $ty_name<$( $m , )*> {
486                $(
487                    $m: $m,
488                )*
489            }
490
491            /// Create a new mutator for a tuple of
492            #[doc = stringify!(tuples!(@count $( $m )*))]
493            /// elements.
494            ///
495            /// # Example
496            ///
497            /// ```
498            /// # fn _foo() -> mutatis::Result<()> {
499            /// use mutatis::{mutators as m, Mutate, Session};
500            ///
501            /// let mut mutator = m::tuple2(m::u8(), m::i16());
502            /// let mut session = Session::new();
503            ///
504            /// let mut value = (42, -1234);
505            /// session.mutate_with(&mut mutator, &mut value)?;
506            ///
507            /// println!("mutated value is {value:?}");
508            /// # Ok(())
509            /// # }
510            /// ```
511            #[allow(non_snake_case)]
512            pub fn $fn_name< $( $m ),* >( $( $m: $m ),* ) -> $ty_name<$( $m , )*> {
513                $ty_name {
514                    $(
515                        $m,
516                    )*
517                }
518            }
519
520            #[allow(non_snake_case)]
521            impl< $( $m , $t, )* > Mutate<( $( $t , )* )> for $ty_name<$( $m , )*>
522            where
523                $(
524                    $m: Mutate<$t>,
525                )*
526            {
527                #[inline]
528                fn mutate(
529                    &mut self,
530                    _c: &mut Candidates,
531                    ( $( $t , )* ): &mut ( $( $t , )* ),
532                ) -> Result<()> {
533                    $(
534                        self.$m.mutate(_c, $t)?;
535                    )*
536                    Ok(())
537                }
538            }
539
540            #[allow(non_snake_case)]
541            impl< $( $t , )* > DefaultMutate for ( $( $t , )* )
542            where
543                $(
544                    $t: DefaultMutate,
545                )*
546            {
547                type DefaultMutate = $ty_name<$( $t::DefaultMutate , )*>;
548            }
549        )*
550    };
551
552    (@count) => { 0 };
553    (@count $head:ident $( $rest:ident )*) => { 1 + tuples!(@count $( $rest )*) };
554}
555
556tuples! {
557    tuple1 -> Tuple1(M0: T0,);
558    tuple2 -> Tuple2(M0: T0, M1: T1,);
559    tuple3 -> Tuple3(M0: T0, M1: T1, M2: T2,);
560    tuple4 -> Tuple4(M0: T0, M1: T1, M2: T2, M3: T3,);
561    tuple5 -> Tuple5(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4,);
562    tuple6 -> Tuple6(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5,);
563    tuple7 -> Tuple7(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6,);
564    tuple8 -> Tuple8(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7,);
565    tuple9 -> Tuple9(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7, M8: T8,);
566    tuple10 -> Tuple10(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7, M8: T8, M9: T9,);
567    tuple11 -> Tuple11(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7, M8: T8, M9: T9, M10: T10,);
568    tuple12 -> Tuple12(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7, M8: T8, M9: T9, M10: T10, M11: T11,);
569    tuple13 -> Tuple13(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7, M8: T8, M9: T9, M10: T10, M11: T11, M12: T12,);
570    tuple14 -> Tuple14(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7, M8: T8, M9: T9, M10: T10, M11: T11, M12: T12, M13: T13,);
571    tuple15 -> Tuple15(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7, M8: T8, M9: T9, M10: T10, M11: T11, M12: T12, M13: T13, M14: T14,);
572    tuple16 -> Tuple16(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7, M8: T8, M9: T9, M10: T10, M11: T11, M12: T12, M13: T13, M14: T14, M15: T15,);
573}
574
575/// A unit mutator.
576#[derive(Clone, Debug, Default)]
577pub struct Unit {
578    _private: (),
579}
580
581/// Create a new unit (a.k.a zero-element tuple) mutator.
582///
583/// # Example
584///
585/// ```
586/// use mutatis::{mutators as m, Error, Mutate, Session};
587///
588/// let mut mutator = m::unit();
589/// let mut session = Session::new();
590///
591/// let mut value = ();
592/// let err = session.mutate_with(&mut mutator, &mut value).unwrap_err();
593///
594/// // Because there is only one possible value for the unit type, the mutator
595/// // is always exhausted.
596/// assert!(err.is_exhausted());
597/// ```
598pub fn unit() -> Unit {
599    Unit { _private: () }
600}
601
602impl Mutate<()> for Unit {
603    #[inline]
604    fn mutate(&mut self, _c: &mut Candidates, _value: &mut ()) -> Result<()> {
605        Ok(())
606    }
607}
608
609/// A mutator for fixed-size arrays.
610///
611/// See the [`array()`] function to create a new `Array` mutator and for example
612/// usage.
613#[derive(Clone, Debug, Default)]
614pub struct Array<const N: usize, M> {
615    mutator: M,
616}
617
618/// Create a new `Array` mutator.
619///
620/// # Example
621///
622/// ```
623/// use mutatis::{mutators as m, Mutate, Session};
624///
625/// let mut mutator = m::array(m::u8());
626/// let mut session = Session::new();
627///
628/// let mut value = [1, 2, 3, 4];
629/// session.mutate_with(&mut mutator, &mut value).unwrap();
630///
631/// println!("mutated array is {value:?}");
632/// ```
633pub fn array<const N: usize, M>(mutator: M) -> Array<N, M> {
634    Array { mutator }
635}
636
637impl<const N: usize, M, T> Mutate<[T; N]> for Array<N, M>
638where
639    M: Mutate<T>,
640{
641    #[inline]
642    fn mutate(&mut self, c: &mut Candidates, value: &mut [T; N]) -> Result<()> {
643        for element in value.iter_mut() {
644            self.mutator.mutate(c, element)?;
645        }
646        Ok(())
647    }
648}
649
650impl<const N: usize, T> DefaultMutate for [T; N]
651where
652    T: DefaultMutate,
653{
654    type DefaultMutate = Array<N, T::DefaultMutate>;
655}
656
657// TODO: cell, refcell
658
659// TODO: duration