1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
extern crate self as fuzzcheck;

use std::ops::{Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};

use fuzzcheck_mutators_derive::make_mutator;

use crate::mutators::map::MapMutator;
use crate::mutators::tuples::{Tuple2, Tuple2Mutator, TupleMutatorWrapper};
use crate::mutators::Wrapper;
use crate::{DefaultMutator, Mutator};

make_mutator! {
    name: RangeMutator,
    default: true,
    type: pub struct Range<Idx> {
        start: Idx,
        end: Idx,
    }
}

make_mutator! {
    name: RangeFromMutator,
    default: true,
    type: pub struct RangeFrom<Idx> {
        start: Idx,
    }
}

make_mutator! {
    name: RangeToMutator,
    default: true,
    type: pub struct RangeTo<Idx> {
        end: Idx,
    }
}

make_mutator! {
    name: RangeToInclusiveMutator,
    default: true,
    type: pub struct RangeToInclusive<Idx> {
        end: Idx,
    }
}

make_mutator! {
    name: RangeFullMutator,
    default: true,
    type: pub struct RangeFull;
}

make_mutator! {
    name: BoundMutator,
    default: true,
    type: pub enum Bound<T> {
        Included(T),
        Excluded(T),
        Unbounded,
    }
}

#[no_coverage]
fn range_inclusive_from_tuple<T: Clone>(t: &(T, T)) -> RangeInclusive<T> {
    t.0.clone()..=t.1.clone()
}
#[no_coverage]
fn tuple_from_range_inclusive<T: Clone>(r: &RangeInclusive<T>) -> Option<(T, T)> {
    Some((r.start().clone(), r.end().clone()))
}

#[no_coverage]
fn range_cplx<T>(_r: &RangeInclusive<T>, orig_cplx: f64) -> f64 {
    orig_cplx
}

pub type RangeInclusiveMutator<T, M> = Wrapper<
    MapMutator<
        (T, T),
        RangeInclusive<T>,
        TupleMutatorWrapper<Tuple2Mutator<M, M>, Tuple2<T, T>>,
        fn(&RangeInclusive<T>) -> Option<(T, T)>,
        fn(&(T, T)) -> RangeInclusive<T>,
        fn(&RangeInclusive<T>, f64) -> f64,
    >,
>;

impl<T, M> RangeInclusiveMutator<T, M>
where
    T: Clone,
    M: Mutator<T> + Clone,
{
    #[no_coverage]
    pub fn new(m: M) -> Self {
        Wrapper(MapMutator::new(
            TupleMutatorWrapper::new(Tuple2Mutator::new(m.clone(), m)),
            tuple_from_range_inclusive,
            range_inclusive_from_tuple,
            range_cplx,
        ))
    }
}
impl<T> DefaultMutator for RangeInclusive<T>
where
    T: 'static + Clone + DefaultMutator,
    T::Mutator: Clone,
{
    type Mutator = RangeInclusiveMutator<T, T::Mutator>;
    #[no_coverage]
    fn default_mutator() -> Self::Mutator {
        Self::Mutator::new(T::default_mutator())
    }
}