fuzzcheck/mutators/vector/
remove.rs

1use super::VecMutator;
2use crate::mutators::mutations::{Mutation, RevertMutation};
3use crate::{Mutator, SubValueProvider};
4
5pub struct Remove;
6
7#[derive(Clone)]
8pub struct RemoveStep {
9    pub idx: usize,
10}
11
12pub struct ConcreteRemove {
13    pub idx: usize,
14}
15pub struct RevertRemove<T> {
16    pub idx: usize,
17    pub element: T,
18}
19
20impl<T, M> RevertMutation<Vec<T>, VecMutator<T, M>> for RevertRemove<T>
21where
22    T: Clone + 'static,
23    M: Mutator<T>,
24{
25    #[coverage(off)]
26    fn revert(
27        self,
28        _mutator: &VecMutator<T, M>,
29        value: &mut Vec<T>,
30        _cache: &mut <VecMutator<T, M> as Mutator<Vec<T>>>::Cache,
31    ) {
32        value.insert(self.idx, self.element);
33    }
34}
35
36impl<T, M> Mutation<Vec<T>, VecMutator<T, M>> for Remove
37where
38    T: Clone + 'static,
39    M: Mutator<T>,
40{
41    type RandomStep = RemoveStep;
42    type Step = RemoveStep;
43    type Concrete<'a> = ConcreteRemove;
44    type Revert = RevertRemove<T>;
45
46    #[coverage(off)]
47    fn default_random_step(&self, mutator: &VecMutator<T, M>, value: &Vec<T>) -> Option<Self::RandomStep> {
48        if mutator.m.max_complexity() == 0. {
49            return None;
50        }
51        if value.len() <= *mutator.len_range.start() {
52            None
53        } else {
54            Some(RemoveStep {
55                idx: mutator.rng.usize(..value.len()),
56            })
57        }
58    }
59    #[coverage(off)]
60    fn random<'a>(
61        _mutator: &VecMutator<T, M>,
62        _value: &Vec<T>,
63        _cache: &<VecMutator<T, M> as Mutator<Vec<T>>>::Cache,
64        random_step: &Self::RandomStep,
65        _max_cplx: f64,
66    ) -> Self::Concrete<'a> {
67        ConcreteRemove { idx: random_step.idx }
68    }
69    #[coverage(off)]
70    fn default_step(
71        &self,
72        mutator: &VecMutator<T, M>,
73        value: &Vec<T>,
74        _cache: &<VecMutator<T, M> as Mutator<Vec<T>>>::Cache,
75    ) -> Option<Self::Step> {
76        if mutator.m.max_complexity() == 0. {
77            return None;
78        }
79        if value.len() <= *mutator.len_range.start() {
80            None
81        } else {
82            Some(RemoveStep { idx: 0 })
83        }
84    }
85    #[coverage(off)]
86    fn from_step<'a>(
87        _mutator: &VecMutator<T, M>,
88        value: &Vec<T>,
89        _cache: &<VecMutator<T, M> as Mutator<Vec<T>>>::Cache,
90        step: &'a mut Self::Step,
91        _subvalue_provider: &dyn SubValueProvider,
92        _max_cplx: f64,
93    ) -> Option<Self::Concrete<'a>> {
94        if step.idx < value.len() {
95            let x = ConcreteRemove { idx: step.idx };
96            step.idx += 1;
97            Some(x)
98        } else {
99            None
100        }
101    }
102    #[coverage(off)]
103    fn apply<'a>(
104        mutation: Self::Concrete<'a>,
105        mutator: &VecMutator<T, M>,
106        value: &mut Vec<T>,
107        cache: &mut <VecMutator<T, M> as Mutator<Vec<T>>>::Cache,
108        _subvalue_provider: &dyn SubValueProvider,
109        _max_cplx: f64,
110    ) -> (Self::Revert, f64) {
111        let removed = value.remove(mutation.idx);
112        let removed_cplx = mutator.m.complexity(&removed, &cache.inner[mutation.idx]);
113        let new_cplx = mutator.complexity_from_inner(cache.sum_cplx - removed_cplx, value.len());
114        (
115            RevertRemove {
116                idx: mutation.idx,
117                element: removed,
118            },
119            new_cplx,
120        )
121    }
122}