use crate::error::ResultExt;
use super::*;
#[derive(Clone, Debug, Default)]
pub struct Duration<S, N> {
secs_mutator: S,
nanos_mutator: N,
}
pub fn duration<S, N>(secs_mutator: S, nanos_mutator: N) -> Duration<S, N> {
Duration {
secs_mutator,
nanos_mutator,
}
}
impl<S, N> Mutate<core::time::Duration> for Duration<S, N>
where
S: Mutate<u64>,
N: Mutate<u32>,
{
#[inline]
fn mutation_count(
&self,
_value: &core::time::Duration,
shrink: bool,
) -> core::option::Option<u32> {
Some(if shrink {
2
} else {
9
})
}
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut core::time::Duration) -> Result<()> {
c.mutation(|ctx| {
let mut secs = value.as_secs();
let mut nanos = value.subsec_nanos();
let result_a = ctx
.mutate_with(&mut self.secs_mutator, &mut secs)
.ignore_exhausted();
let result_b = ctx
.mutate_with(&mut self.nanos_mutator, &mut nanos)
.ignore_exhausted();
let nanos = nanos.min(999_999_999);
*value = core::time::Duration::new(secs, nanos);
result_a.or(result_b)
})?;
if c.shrink() {
c.mutation(|_| Ok(*value = core::time::Duration::ZERO))?;
} else {
c.mutation(|_| Ok(*value = core::time::Duration::ZERO))?;
c.mutation(|_| Ok(*value = core::time::Duration::MAX))?;
c.mutation(|_| Ok(*value = core::time::Duration::from_hours(1)))?;
c.mutation(|_| Ok(*value = core::time::Duration::from_mins(1)))?;
c.mutation(|_| Ok(*value = core::time::Duration::from_secs(1)))?;
c.mutation(|_| Ok(*value = core::time::Duration::from_millis(1)))?;
c.mutation(|_| Ok(*value = core::time::Duration::from_micros(1)))?;
c.mutation(|_| Ok(*value = core::time::Duration::from_nanos(1)))?;
}
Ok(())
}
}
impl<S, N> Generate<core::time::Duration> for Duration<S, N>
where
S: Generate<u64>,
N: Generate<u32>,
{
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<core::time::Duration> {
let secs = self.secs_mutator.generate(ctx)?;
let mut nanos = self.nanos_mutator.generate(ctx)?;
if nanos > 999_999_999 {
nanos = 999_999_999;
}
Ok(core::time::Duration::new(secs, nanos))
}
}
impl DefaultMutate for core::time::Duration {
type DefaultMutate = Duration<U64, U32>;
}