Skip to main content

mutatis/mutators/
core_impls.rs

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