use super::*;
use crate::Result;
use core::{cmp, ops};
mod atomic;
mod cell;
mod duration;
mod non_zero;
mod option;
mod phantom;
mod ranges;
mod ref_cell;
mod result;
mod reverse;
mod unsafe_cell;
mod wrapping;
pub use atomic::*;
pub use cell::*;
pub use duration::*;
pub use non_zero::*;
pub use option::*;
pub use phantom::*;
pub use ranges::*;
pub use ref_cell::*;
pub use result::*;
pub use reverse::*;
pub use unsafe_cell::*;
pub use wrapping::*;
#[derive(Clone, Debug, Default)]
pub struct Bool {
_private: (),
}
pub fn bool() -> Bool {
Bool { _private: () }
}
impl Mutate<bool> for Bool {
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut bool) -> Result<()> {
if !c.shrink() || *value {
c.mutation(|_ctx| Ok(*value = !*value))?;
}
Ok(())
}
#[inline]
fn mutation_count(&self, value: &bool, shrink: bool) -> core::option::Option<u32> {
Some(if !shrink || *value { 1 } else { 0 })
}
}
impl Generate<bool> for Bool {
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<bool> {
Ok(ctx.rng().gen_bool())
}
}
impl DefaultMutate for bool {
type DefaultMutate = Bool;
}
macro_rules! ints {
(
$(
$fn_name:ident -> $ty_name:ident : $method:ident for $ty:ty ;
)*
) => {
$(
#[doc = concat!("`", stringify!($fn_name), "`")]
#[doc = concat!("[`", stringify!($fn_name), "()`]")]
#[derive(Clone, Debug, Default)]
pub struct $ty_name {
_private: (),
}
#[doc = concat!("`", stringify!($ty), "`")]
#[doc = concat!("let mut mutator = m::", stringify!($fn_name), "();")]
pub fn $fn_name() -> $ty_name {
$ty_name { _private: () }
}
impl Mutate<$ty> for $ty_name {
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut $ty) -> Result<()> {
if c.shrink() && *value == 0 {
return Ok(());
}
c.mutation(|ctx| {
*value = if ctx.shrink() {
ctx.rng().inner().gen_range(0..*value)
} else {
ctx.rng().$method()
};
Ok(())
})
}
#[inline]
fn mutation_count(&self, value: &$ty, shrink: bool) -> core::option::Option<u32> {
Some(if shrink && *value == 0 { 0 } else { 1 })
}
}
impl DefaultMutate for $ty {
type DefaultMutate = $ty_name;
}
impl Generate<$ty> for $ty_name {
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<$ty> {
Ok(ctx.rng().$method())
}
}
impl MutateInRange<$ty> for $ty_name {
#[inline]
fn mutate_in_range(
&mut self,
c: &mut Candidates,
value: &mut $ty,
range: &ops::RangeInclusive<$ty>,
) -> Result<()> {
let start = *range.start();
let end = *range.end();
if start > end {
return Err(Error::invalid_range());
}
if *value == start && c.shrink() {
return Ok(());
}
c.mutation(|ctx| {
let end = if ctx.shrink() {
cmp::min(*value, end)
} else {
end
};
*value = ctx.rng().inner().gen_range(start..=end);
Ok(())
})
}
}
)*
};
}
ints! {
u8 -> U8 : gen_u8 for u8;
u16 -> U16 : gen_u16 for u16;
u32 -> U32 : gen_u32 for u32;
u64 -> U64 : gen_u64 for u64;
u128 -> U128 : gen_u128 for u128;
usize -> Usize : gen_usize for usize;
i8 -> I8 : gen_i8 for i8;
i16 -> I16 : gen_i16 for i16;
i32 -> I32 : gen_i32 for i32;
i64 -> I64 : gen_i64 for i64;
i128 -> I128 : gen_i128 for i128;
isize -> Isize : gen_isize for isize;
}
#[derive(Clone, Debug, Default)]
pub struct Char {
_private: (),
}
pub fn char() -> Char {
Char { _private: () }
}
impl Mutate<char> for Char {
#[inline]
fn mutation_count(&self, value: &char, shrink: bool) -> core::option::Option<u32> {
Some(if shrink { (*value != '\0') as u32 } else { 8 })
}
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut char) -> Result<()> {
if c.shrink() {
if *value != '\0' {
c.mutation(|ctx| {
*value = ctx.rng().inner().gen_range('\0'..*value);
Ok(())
})?;
}
Ok(())
} else {
let ch = |x| char::from_u32(x).unwrap_or_else(|| panic!("invalid char: {x:#x}"));
let mut char_range = |start, end| mrange(ch(start)..=ch(end)).mutate(c, value);
char_range(0x20, 0x7E)?;
char_range(0x0000, 0xFFFF)?;
char_range(0x10000, 0x14FFF)?;
char_range(0x16000, 0x18FFF)?;
char_range(0x1A000, 0x1FFFF)?;
char_range(0x20000, 0x2FFFF)?;
char_range(0x30000, 0x32FFF)?;
c.mutation(|ctx| Ok(*value = ctx.rng().inner().r#gen()))?;
Ok(())
}
}
}
impl DefaultMutate for char {
type DefaultMutate = Char;
}
impl Generate<char> for Char {
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<char> {
Ok(ctx.rng().inner().r#gen())
}
}
impl MutateInRange<char> for Char {
#[inline]
fn mutate_in_range(
&mut self,
c: &mut Candidates,
value: &mut char,
range: &ops::RangeInclusive<char>,
) -> Result<()> {
let start = *range.start();
let end = *range.end();
if start > end {
return Err(Error::invalid_range());
}
if *value == start && c.shrink() {
return Ok(());
}
c.mutation(|ctx| {
let end = if ctx.shrink() {
core::cmp::min(*value, end)
} else {
end
};
*value = ctx.rng().inner().gen_range(start..=end);
Ok(())
})
}
}
#[derive(Clone, Debug, Default)]
pub struct AsciiChar {
_private: (),
}
pub fn ascii_char() -> AsciiChar {
AsciiChar { _private: () }
}
impl Mutate<char> for AsciiChar {
#[inline]
fn mutation_count(&self, value: &char, shrink: bool) -> core::option::Option<u32> {
Some(if shrink { (*value != '\0') as u32 } else { 1 })
}
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut char) -> Result<()> {
if c.shrink() {
if *value != '\0' {
c.mutation(|ctx| {
*value = ctx.rng().inner().gen_range('\0'..*value);
Ok(())
})?;
}
Ok(())
} else {
let ch = |x| char::from_u32(x).unwrap_or_else(|| panic!("invalid char: {x:#x}"));
let mut char_range = |start, end| mrange(ch(start)..=ch(end)).mutate(c, value);
char_range(0x00, 0x7F)?;
Ok(())
}
}
}
impl Generate<char> for AsciiChar {
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<char> {
self.generate_via_mutate(ctx, 1)
}
}
#[derive(Default)]
pub struct F32 {
_private: (),
}
pub fn f32() -> F32 {
F32 { _private: () }
}
impl Mutate<f32> for F32 {
#[inline]
fn mutation_count(&self, value: &f32, shrink: bool) -> core::option::Option<u32> {
Some(if shrink {
if *value == 0.0 {
0
} else if value.is_nan() || value.is_infinite() {
9
} else {
1
}
} else {
12
})
}
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut f32) -> Result<()> {
let special_finite = |c: &mut Candidates, value: &mut f32| -> Result<()> {
c.mutation(|_| Ok(*value = 0.0))?;
c.mutation(|_| Ok(*value = 1.0))?;
c.mutation(|_| Ok(*value = -1.0))?;
c.mutation(|_| Ok(*value = f32::EPSILON))?;
c.mutation(|_| Ok(*value = f32::MIN_POSITIVE))?;
c.mutation(|_| Ok(*value = f32::MAX))?;
c.mutation(|_| Ok(*value = f32::MIN))?;
Ok(())
};
let finite = |c: &mut Candidates, value: &mut f32| -> Result<()> {
special_finite(c, value)?;
c.mutation(|ctx| Ok(*value = ctx.rng().inner().r#gen::<f32>() * f32::MAX))?;
c.mutation(|ctx| Ok(*value = ctx.rng().inner().r#gen::<f32>() * f32::MIN))?;
Ok(())
};
if c.shrink() {
if *value == 0.0 {
return Ok(());
}
if value.is_nan() || value.is_infinite() {
return finite(c, value);
}
c.mutation(|ctx| Ok(*value *= ctx.rng().inner().r#gen::<f32>()))?;
Ok(())
} else {
finite(c, value)?;
c.mutation(|_| Ok(*value = f32::INFINITY))?;
c.mutation(|_| Ok(*value = f32::NEG_INFINITY))?;
c.mutation(|_| Ok(*value = f32::NAN))?;
Ok(())
}
}
}
impl Generate<f32> for F32 {
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<f32> {
Ok(ctx.rng().inner().r#gen::<f32>() * f32::MAX)
}
}
impl DefaultMutate for f32 {
type DefaultMutate = F32;
}
#[derive(Default)]
pub struct F64 {
_private: (),
}
pub fn f64() -> F64 {
F64 { _private: () }
}
impl Mutate<f64> for F64 {
#[inline]
fn mutation_count(&self, value: &f64, shrink: bool) -> core::option::Option<u32> {
Some(if shrink {
if *value == 0.0 {
0
} else if value.is_nan() || value.is_infinite() {
9
} else {
1
}
} else {
12
})
}
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut f64) -> Result<()> {
let special_finite = |c: &mut Candidates, value: &mut f64| -> Result<()> {
c.mutation(|_| Ok(*value = 0.0))?;
c.mutation(|_| Ok(*value = 1.0))?;
c.mutation(|_| Ok(*value = -1.0))?;
c.mutation(|_| Ok(*value = f64::EPSILON))?;
c.mutation(|_| Ok(*value = f64::MIN_POSITIVE))?;
c.mutation(|_| Ok(*value = f64::MAX))?;
c.mutation(|_| Ok(*value = f64::MIN))?;
Ok(())
};
let finite = |c: &mut Candidates, value: &mut f64| -> Result<()> {
special_finite(c, value)?;
c.mutation(|ctx| Ok(*value = ctx.rng().inner().r#gen::<f64>() * f64::MAX))?;
c.mutation(|ctx| Ok(*value = ctx.rng().inner().r#gen::<f64>() * f64::MIN))?;
Ok(())
};
if c.shrink() {
if *value == 0.0 {
return Ok(());
}
if value.is_nan() || value.is_infinite() {
return finite(c, value);
}
c.mutation(|ctx| Ok(*value *= ctx.rng().inner().r#gen::<f64>()))?;
Ok(())
} else {
finite(c, value)?;
c.mutation(|_| Ok(*value = f64::INFINITY))?;
c.mutation(|_| Ok(*value = f64::NEG_INFINITY))?;
c.mutation(|_| Ok(*value = f64::NAN))?;
Ok(())
}
}
}
impl Generate<f64> for F64 {
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<f64> {
Ok(ctx.rng().inner().r#gen::<f64>() * f64::MAX)
}
}
impl DefaultMutate for f64 {
type DefaultMutate = F64;
}
macro_rules! tuples {
( $( $fn_name:ident -> $ty_name:ident ( $( $m:ident : $t:ident , )* ) ; )* ) => {
$(
/// A mutator for tuples.
#[derive(Clone, Debug, Default)]
#[allow(non_snake_case)]
pub struct $ty_name<$( $m , )*> {
$(
$m: $m,
)*
}
#[doc = stringify!(tuples!(@count $( $m )*))]
#[allow(non_snake_case)]
pub fn $fn_name< $( $m ),* >( $( $m: $m ),* ) -> $ty_name<$( $m , )*> {
$ty_name {
$(
$m,
)*
}
}
#[allow(non_snake_case)]
impl< $( $m , $t, )* > Mutate<( $( $t , )* )> for $ty_name<$( $m , )*>
where
$(
$m: Mutate<$t>,
)*
{
#[inline]
fn mutate(
&mut self,
_c: &mut Candidates,
( $( $t , )* ): &mut ( $( $t , )* ),
) -> Result<()> {
$(
self.$m.mutate(_c, $t)?;
)*
Ok(())
}
#[inline]
fn mutation_count(
&self,
( $( $t , )* ): &( $( $t , )* ),
_shrink: bool,
) -> core::option::Option<u32> {
Some(0 $( + self.$m.mutation_count($t, _shrink)? )*)
}
}
#[allow(non_snake_case)]
impl< $( $m , $t, )* > Generate<( $( $t , )* )> for $ty_name<$( $m , )*>
where
$(
$m: Generate<$t>,
)*
{
#[inline]
fn generate(&mut self, _ctx: &mut Context) -> Result<( $( $t , )* )> {
Ok(( $( self.$m.generate(_ctx)? , )* ))
}
}
#[allow(non_snake_case)]
impl< $( $t , )* > DefaultMutate for ( $( $t , )* )
where
$(
$t: DefaultMutate,
)*
{
type DefaultMutate = $ty_name<$( $t::DefaultMutate , )*>;
}
)*
};
(@count) => { 0 };
(@count $head:ident $( $rest:ident )*) => { 1 + tuples!(@count $( $rest )*) };
}
tuples! {
tuple1 -> Tuple1(M0: T0,);
tuple2 -> Tuple2(M0: T0, M1: T1,);
tuple3 -> Tuple3(M0: T0, M1: T1, M2: T2,);
tuple4 -> Tuple4(M0: T0, M1: T1, M2: T2, M3: T3,);
tuple5 -> Tuple5(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4,);
tuple6 -> Tuple6(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5,);
tuple7 -> Tuple7(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6,);
tuple8 -> Tuple8(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7,);
tuple9 -> Tuple9(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7, M8: T8,);
tuple10 -> Tuple10(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7, M8: T8, M9: T9,);
tuple11 -> Tuple11(M0: T0, M1: T1, M2: T2, M3: T3, M4: T4, M5: T5, M6: T6, M7: T7, M8: T8, M9: T9, M10: T10,);
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,);
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,);
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,);
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,);
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,);
}
#[derive(Clone, Debug, Default)]
pub struct Unit {
_private: (),
}
pub fn unit() -> Unit {
Unit { _private: () }
}
impl Mutate<()> for Unit {
#[inline]
fn mutate(&mut self, _c: &mut Candidates, _value: &mut ()) -> Result<()> {
Ok(())
}
#[inline]
fn mutation_count(&self, _value: &(), _shrink: bool) -> core::option::Option<u32> {
Some(0)
}
}
impl Generate<()> for Unit {
#[inline]
fn generate(&mut self, _ctx: &mut Context) -> Result<()> {
Ok(())
}
}
impl DefaultMutate for () {
type DefaultMutate = Unit;
}
#[derive(Clone, Debug, Default)]
pub struct Array<const N: usize, M> {
mutator: M,
}
pub fn array<const N: usize, M>(mutator: M) -> Array<N, M> {
Array { mutator }
}
impl<const N: usize, M, T> Mutate<[T; N]> for Array<N, M>
where
M: Mutate<T>,
{
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut [T; N]) -> Result<()> {
for element in value.iter_mut() {
self.mutator.mutate(c, element)?;
}
Ok(())
}
#[inline]
fn mutation_count(&self, value: &[T; N], shrink: bool) -> core::option::Option<u32> {
let mut count = 0u32;
for element in value.iter() {
count += self.mutator.mutation_count(element, shrink)?;
}
Some(count)
}
}
impl<const N: usize, M, T> Generate<[T; N]> for Array<N, M>
where
M: Generate<T>,
{
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<[T; N]> {
let mut arr: [core::mem::MaybeUninit<T>; N] =
core::array::from_fn(|_| core::mem::MaybeUninit::uninit());
for elem in arr.iter_mut() {
elem.write(self.mutator.generate(ctx)?);
}
Ok(unsafe { core::mem::transmute_copy(&arr) })
}
}
impl<const N: usize, T> DefaultMutate for [T; N]
where
T: DefaultMutate,
{
type DefaultMutate = Array<N, T::DefaultMutate>;
}