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