use super::*;
#[derive(Clone, Debug, Default)]
pub struct Range<M> {
mutator: M,
}
pub fn range<M>(mutator: M) -> Range<M> {
Range { mutator }
}
impl<M, T> Mutate<core::ops::Range<T>> for Range<M>
where
M: Mutate<T>,
{
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut core::ops::Range<T>) -> Result<()> {
self.mutator.mutate(c, &mut value.start)?;
self.mutator.mutate(c, &mut value.end)?;
Ok(())
}
#[inline]
fn mutation_count(
&self,
value: &core::ops::Range<T>,
shrink: bool,
) -> core::option::Option<u32> {
let mut count = 0u32;
count += self.mutator.mutation_count(&value.start, shrink)?;
count += self.mutator.mutation_count(&value.end, shrink)?;
Some(count)
}
}
impl<M, T> Generate<core::ops::Range<T>> for Range<M>
where
M: Generate<T>,
{
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<core::ops::Range<T>> {
let start = self.mutator.generate(ctx)?;
let end = self.mutator.generate(ctx)?;
Ok(start..end)
}
}
impl<T> DefaultMutate for core::ops::Range<T>
where
T: DefaultMutate,
{
type DefaultMutate = Range<T::DefaultMutate>;
}
#[derive(Clone, Debug, Default)]
pub struct RangeFrom<M> {
mutator: M,
}
pub fn range_from<M>(mutator: M) -> RangeFrom<M> {
RangeFrom { mutator }
}
impl<M, T> Mutate<core::ops::RangeFrom<T>> for RangeFrom<M>
where
M: Mutate<T>,
{
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut core::ops::RangeFrom<T>) -> Result<()> {
self.mutator.mutate(c, &mut value.start)
}
#[inline]
fn mutation_count(
&self,
value: &core::ops::RangeFrom<T>,
shrink: bool,
) -> core::option::Option<u32> {
self.mutator.mutation_count(&value.start, shrink)
}
}
impl<M, T> Generate<core::ops::RangeFrom<T>> for RangeFrom<M>
where
M: Generate<T>,
{
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<core::ops::RangeFrom<T>> {
let start = self.mutator.generate(ctx)?;
Ok(start..)
}
}
impl<T> DefaultMutate for core::ops::RangeFrom<T>
where
T: DefaultMutate,
{
type DefaultMutate = RangeFrom<T::DefaultMutate>;
}
#[derive(Clone, Debug, Default)]
pub struct RangeInclusive<M> {
mutator: M,
}
pub fn range_inclusive<M>(mutator: M) -> RangeInclusive<M> {
RangeInclusive { mutator }
}
impl<M, T> Mutate<core::ops::RangeInclusive<T>> for RangeInclusive<M>
where
M: Mutate<T>,
T: Default + Clone,
{
#[inline]
fn mutation_count(
&self,
_value: &core::ops::RangeInclusive<T>,
_shrink: bool,
) -> core::option::Option<u32> {
Some(2)
}
#[inline]
fn mutate(
&mut self,
c: &mut Candidates,
value: &mut core::ops::RangeInclusive<T>,
) -> Result<()> {
c.mutation(|ctx| {
let mut start = value.start().clone();
let result = ctx.mutate_with(&mut self.mutator, &mut start);
let end = value.end().clone();
*value = start..=end;
result
})?;
c.mutation(|ctx| {
let start = value.start().clone();
let mut end = value.end().clone();
let result = ctx.mutate_with(&mut self.mutator, &mut end);
*value = start..=end;
result
})?;
Ok(())
}
}
impl<M, T> Generate<core::ops::RangeInclusive<T>> for RangeInclusive<M>
where
M: Generate<T>,
T: Default + Clone,
{
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<core::ops::RangeInclusive<T>> {
let start = self.mutator.generate(ctx)?;
let end = self.mutator.generate(ctx)?;
Ok(start..=end)
}
}
impl<T> DefaultMutate for core::ops::RangeInclusive<T>
where
T: DefaultMutate + Default + Clone,
{
type DefaultMutate = RangeInclusive<T::DefaultMutate>;
}
#[derive(Clone, Debug, Default)]
pub struct RangeTo<M> {
mutator: M,
}
pub fn range_to<M>(mutator: M) -> RangeTo<M> {
RangeTo { mutator }
}
impl<M, T> Mutate<core::ops::RangeTo<T>> for RangeTo<M>
where
M: Mutate<T>,
{
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut core::ops::RangeTo<T>) -> Result<()> {
self.mutator.mutate(c, &mut value.end)
}
#[inline]
fn mutation_count(
&self,
value: &core::ops::RangeTo<T>,
shrink: bool,
) -> core::option::Option<u32> {
self.mutator.mutation_count(&value.end, shrink)
}
}
impl<M, T> Generate<core::ops::RangeTo<T>> for RangeTo<M>
where
M: Generate<T>,
{
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<core::ops::RangeTo<T>> {
let end = self.mutator.generate(ctx)?;
Ok(..end)
}
}
impl<T> DefaultMutate for core::ops::RangeTo<T>
where
T: DefaultMutate,
{
type DefaultMutate = RangeTo<T::DefaultMutate>;
}
#[derive(Clone, Debug, Default)]
pub struct RangeToInclusive<M> {
mutator: M,
}
pub fn range_to_inclusive<M>(mutator: M) -> RangeToInclusive<M> {
RangeToInclusive { mutator }
}
impl<M, T> Mutate<core::ops::RangeToInclusive<T>> for RangeToInclusive<M>
where
M: Mutate<T>,
{
#[inline]
fn mutate(
&mut self,
c: &mut Candidates,
value: &mut core::ops::RangeToInclusive<T>,
) -> Result<()> {
self.mutator.mutate(c, &mut value.end)
}
#[inline]
fn mutation_count(
&self,
value: &core::ops::RangeToInclusive<T>,
shrink: bool,
) -> core::option::Option<u32> {
self.mutator.mutation_count(&value.end, shrink)
}
}
impl<M, T> Generate<core::ops::RangeToInclusive<T>> for RangeToInclusive<M>
where
M: Generate<T>,
{
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<core::ops::RangeToInclusive<T>> {
let end = self.mutator.generate(ctx)?;
Ok(..=end)
}
}
impl<T> DefaultMutate for core::ops::RangeToInclusive<T>
where
T: DefaultMutate,
{
type DefaultMutate = RangeToInclusive<T::DefaultMutate>;
}
#[derive(Clone, Debug, Default)]
pub struct Bound<M> {
mutator: M,
}
pub fn bound<M>(mutator: M) -> Bound<M> {
Bound { mutator }
}
impl<M, T> Mutate<core::ops::Bound<T>> for Bound<M>
where
M: Generate<T>,
{
#[inline]
fn mutation_count(
&self,
value: &core::ops::Bound<T>,
shrink: bool,
) -> core::option::Option<u32> {
match value {
core::ops::Bound::Included(v) => {
let mut count = 0u32;
count += self.mutator.mutation_count(v, shrink)?;
count += !shrink as u32;
count += 1;
Some(count)
}
core::ops::Bound::Excluded(v) => {
let mut count = 0u32;
count += self.mutator.mutation_count(v, shrink)?;
count += 1;
count += 1;
Some(count)
}
core::ops::Bound::Unbounded => {
let mut count = 0u32;
count += 1;
count += !shrink as u32;
Some(count)
}
}
}
#[inline]
fn mutate(&mut self, c: &mut Candidates, value: &mut core::ops::Bound<T>) -> Result<()> {
match value {
core::ops::Bound::Included(v) => {
self.mutator.mutate(c, v)?;
if !c.shrink() {
c.mutation(|ctx| {
*value = core::ops::Bound::Excluded(self.mutator.generate(ctx)?);
Ok(())
})?;
}
c.mutation(|_| {
*value = core::ops::Bound::Unbounded;
Ok(())
})?;
}
core::ops::Bound::Excluded(v) => {
self.mutator.mutate(c, v)?;
c.mutation(|ctx| {
*value = core::ops::Bound::Included(self.mutator.generate(ctx)?);
Ok(())
})?;
c.mutation(|_| {
*value = core::ops::Bound::Unbounded;
Ok(())
})?;
}
core::ops::Bound::Unbounded => {
c.mutation(|ctx| {
*value = core::ops::Bound::Included(self.mutator.generate(ctx)?);
Ok(())
})?;
if !c.shrink() {
c.mutation(|ctx| {
*value = core::ops::Bound::Excluded(self.mutator.generate(ctx)?);
Ok(())
})?;
}
}
}
Ok(())
}
}
impl<M, T> Generate<core::ops::Bound<T>> for Bound<M>
where
M: Generate<T>,
{
#[inline]
fn generate(&mut self, ctx: &mut Context) -> Result<core::ops::Bound<T>> {
match ctx.rng().gen_u8() % 3 {
0 => Ok(core::ops::Bound::Included(self.mutator.generate(ctx)?)),
1 => Ok(core::ops::Bound::Excluded(self.mutator.generate(ctx)?)),
_ => Ok(core::ops::Bound::Unbounded),
}
}
}
impl<T> DefaultMutate for core::ops::Bound<T>
where
T: DefaultMutate,
T::DefaultMutate: Generate<T>,
{
type DefaultMutate = Bound<T::DefaultMutate>;
}