fuzzcheck/mutators/
bool.rs

1use std::any::Any;
2
3use crate::{DefaultMutator, Mutator};
4
5/// Default mutator for `bool`
6#[derive(Default)]
7pub struct BoolMutator {
8    rng: fastrand::Rng,
9}
10
11impl DefaultMutator for bool {
12    type Mutator = BoolMutator;
13    #[coverage(off)]
14    fn default_mutator() -> Self::Mutator {
15        <_>::default()
16    }
17}
18
19#[doc(hidden)]
20#[derive(Clone, Copy)]
21pub enum ArbitraryStep {
22    Never = 0,
23    Once = 1,
24    Twice = 2,
25}
26impl Default for ArbitraryStep {
27    #[coverage(off)]
28    fn default() -> Self {
29        Self::Never
30    }
31}
32
33const BOOL_COMPLEXITY: f64 = 1.0;
34const INITIAL_MUTATION_STEP: bool = false;
35
36impl Mutator<bool> for BoolMutator {
37    #[doc(hidden)]
38    type Cache = ();
39    #[doc(hidden)]
40    type MutationStep = bool;
41    #[doc(hidden)]
42    type ArbitraryStep = ArbitraryStep;
43    #[doc(hidden)]
44    type UnmutateToken = bool;
45
46    #[doc(hidden)]
47    #[coverage(off)]
48    fn initialize(&self) {}
49
50    #[doc(hidden)]
51    #[coverage(off)]
52    fn default_arbitrary_step(&self) -> Self::ArbitraryStep {
53        <_>::default()
54    }
55
56    #[doc(hidden)]
57    #[coverage(off)]
58    fn is_valid(&self, _value: &bool) -> bool {
59        true
60    }
61
62    #[doc(hidden)]
63    #[coverage(off)]
64    fn validate_value(&self, _value: &bool) -> Option<Self::Cache> {
65        Some(())
66    }
67
68    #[doc(hidden)]
69    #[coverage(off)]
70    fn default_mutation_step(&self, _value: &bool, _cache: &Self::Cache) -> Self::MutationStep {
71        INITIAL_MUTATION_STEP
72    }
73
74    #[doc(hidden)]
75    #[coverage(off)]
76    fn global_search_space_complexity(&self) -> f64 {
77        1.0
78    }
79    #[doc(hidden)]
80    #[coverage(off)]
81    fn max_complexity(&self) -> f64 {
82        BOOL_COMPLEXITY
83    }
84    #[doc(hidden)]
85    #[coverage(off)]
86    fn min_complexity(&self) -> f64 {
87        BOOL_COMPLEXITY
88    }
89    #[doc(hidden)]
90    #[coverage(off)]
91    fn complexity(&self, _value: &bool, _cache: &Self::Cache) -> f64 {
92        BOOL_COMPLEXITY
93    }
94    #[doc(hidden)]
95    #[coverage(off)]
96    fn ordered_arbitrary(&self, step: &mut Self::ArbitraryStep, max_cplx: f64) -> Option<(bool, f64)> {
97        if max_cplx < self.min_complexity() {
98            return None;
99        }
100        match step {
101            ArbitraryStep::Never => {
102                *step = ArbitraryStep::Once;
103                Some((false, BOOL_COMPLEXITY))
104            }
105            ArbitraryStep::Once => {
106                *step = ArbitraryStep::Twice;
107                Some((true, BOOL_COMPLEXITY))
108            }
109            ArbitraryStep::Twice => None,
110        }
111    }
112    #[doc(hidden)]
113    #[coverage(off)]
114    fn random_arbitrary(&self, _max_cplx: f64) -> (bool, f64) {
115        (self.rng.bool(), BOOL_COMPLEXITY)
116    }
117    #[doc(hidden)]
118    #[coverage(off)]
119    fn ordered_mutate(
120        &self,
121        value: &mut bool,
122        _cache: &mut Self::Cache,
123        step: &mut Self::MutationStep,
124        _subvalue_provider: &dyn crate::SubValueProvider,
125        max_cplx: f64,
126    ) -> Option<(Self::UnmutateToken, f64)> {
127        if max_cplx < self.min_complexity() {
128            return None;
129        }
130        if !*step {
131            *step = !*step;
132            Some((std::mem::replace(value, !*value), BOOL_COMPLEXITY))
133        } else {
134            None
135        }
136    }
137
138    #[doc(hidden)]
139    #[coverage(off)]
140    fn random_mutate(&self, value: &mut bool, _cache: &mut Self::Cache, _max_cplx: f64) -> (Self::UnmutateToken, f64) {
141        (std::mem::replace(value, !*value), BOOL_COMPLEXITY)
142    }
143
144    #[doc(hidden)]
145    #[coverage(off)]
146    fn unmutate(&self, value: &mut bool, _cache: &mut Self::Cache, t: Self::UnmutateToken) {
147        *value = t;
148    }
149
150    #[doc(hidden)]
151    #[coverage(off)]
152    fn visit_subvalues<'a>(&self, _value: &'a bool, _cache: &'a Self::Cache, _visit: &mut dyn FnMut(&'a dyn Any, f64)) {
153    }
154}