1use crate::DefaultMutator;
2use fastrand::Rng;
3use fuzzcheck_traits::Mutator;
4
5use std::ops::Range;
6use std::{iter::repeat, marker::PhantomData};
7
8pub struct VecMutator<T: Clone, M: Mutator<T>> {
9 pub rng: Rng,
10 pub m: M,
11 _phantom: PhantomData<T>,
12}
13impl<T: Clone, M: Mutator<T>> VecMutator<T, M> {
14 pub fn new(mutator: M) -> Self {
15 Self {
16 rng: Rng::default(),
17 m: mutator,
18 _phantom: <_>::default(),
19 }
20 }
21}
22impl<T: Clone, M: Mutator<T>> Default for VecMutator<T, M>
23where
24 M: Default,
25{
26 fn default() -> Self {
27 Self {
28 rng: Rng::default(),
29 m: M::default(),
30 _phantom: <_>::default(),
31 }
32 }
33}
34impl<T: Clone> DefaultMutator for Vec<T>
35where
36 T: DefaultMutator,
37{
38 type Mutator = VecMutator<T, <T as DefaultMutator>::Mutator>;
39 fn default_mutator() -> Self::Mutator {
40 Self::Mutator::new(T::default_mutator())
41 }
42}
43
44#[derive(Clone)]
45pub struct MutationStep<S> {
46 inner: Vec<S>,
47 element_step: usize,
48}
49
50#[derive(Clone)]
51pub struct VecMutatorCache<C> {
52 inner: Vec<C>,
53 sum_cplx: f64,
54}
55impl<C> Default for VecMutatorCache<C> {
56 fn default() -> Self {
57 Self {
58 inner: Vec::new(),
59 sum_cplx: 0.0,
60 }
61 }
62}
63
64pub enum UnmutateVecToken<T: Clone, M: Mutator<T>> {
65 Element(usize, M::UnmutateToken, f64),
66 Remove(usize, f64),
67 RemoveMany(Range<usize>, f64),
68 Insert(usize, T, M::Cache),
69 InsertMany(usize, Vec<T>, <VecMutator<T, M> as Mutator<Vec<T>>>::Cache),
70 Replace(Vec<T>, <VecMutator<T, M> as Mutator<Vec<T>>>::Cache),
71 Nothing,
72}
73
74impl<T: Clone, M: Mutator<T>> VecMutator<T, M> {
75 fn mutate_element(
76 &self,
77 value: &mut Vec<T>,
78 cache: &mut VecMutatorCache<M::Cache>,
79 step: &mut MutationStep<M::MutationStep>,
80 idx: usize,
81 spare_cplx: f64,
82 ) -> Option<UnmutateVecToken<T, M>> {
83 let el = &mut value[idx];
84 let el_cache = &mut cache.inner[idx];
85 let el_step = &mut step.inner[idx];
86
87 let old_cplx = self.m.complexity(&el, el_cache);
88
89 if let Some(token) = self.m.ordered_mutate(el, el_cache, el_step, spare_cplx + old_cplx) {
90 let new_cplx = self.m.complexity(&el, el_cache);
91 cache.sum_cplx += new_cplx - old_cplx;
92 Some(UnmutateVecToken::Element(idx, token, old_cplx - new_cplx))
93 } else {
94 None
95 }
96 }
97
98 fn insert_element(
99 &self,
100 value: &mut Vec<T>,
101 cache: &mut VecMutatorCache<M::Cache>,
102 spare_cplx: f64,
103 ) -> Option<UnmutateVecToken<T, M>> {
104 let idx = if value.is_empty() {
105 0
106 } else {
107 self.rng.usize(0..value.len())
108 };
109
110 let (el, el_cache) = self.m.random_arbitrary(spare_cplx);
111 let el_cplx = self.m.complexity(&el, &el_cache);
112
113 value.insert(idx, el);
114 cache.inner.insert(idx, el_cache);
115
116 let token = UnmutateVecToken::Remove(idx, el_cplx);
117
118 cache.sum_cplx += el_cplx;
119
120 Some(token)
121 }
122
123 fn remove_element(
124 &self,
125 value: &mut Vec<T>,
126 cache: &mut VecMutatorCache<M::Cache>,
127 ) -> Option<UnmutateVecToken<T, M>> {
128 if value.is_empty() {
129 return None;
130 }
131
132 let idx = self.rng.usize(0..value.len());
133
134 let el = &value[idx];
135 let el_cplx = self.m.complexity(&el, &cache.inner[idx]);
136
137 let removed_el = value.remove(idx);
138 let removed_el_cache = cache.inner.remove(idx);
139
140 let token = UnmutateVecToken::Insert(idx, removed_el, removed_el_cache);
141
142 cache.sum_cplx -= el_cplx;
143
144 Some(token)
145 }
146
147 fn remove_many_elements(
148 &self,
149 value: &mut Vec<T>,
150 cache: &mut VecMutatorCache<M::Cache>,
151 ) -> Option<UnmutateVecToken<T, M>> {
152 if value.is_empty() {
153 return None;
154 }
155 let start_idx = if value.len() == 1 {
156 0
157 } else {
158 self.rng.usize(0..value.len() - 1)
159 };
160 let end_idx = std::cmp::min(value.len(), start_idx + self.rng.usize(1..10));
161 let (removed_elements, removed_cache) = {
162 let removed_elements: Vec<_> = value.drain(start_idx..end_idx).collect();
163 let removed_cache: Vec<_> = cache.inner.drain(start_idx..end_idx).collect();
164 (removed_elements, removed_cache)
165 };
166 let removed_els_cplx = removed_elements
167 .iter()
168 .zip(removed_cache.iter())
169 .fold(0.0, |cplx, (v, c)| self.m.complexity(&v, &c) + cplx);
170
171 let removed_cache = VecMutatorCache {
172 inner: removed_cache,
173 sum_cplx: removed_els_cplx,
174 };
175
176 let token = UnmutateVecToken::InsertMany(start_idx, removed_elements, removed_cache);
177
178 cache.sum_cplx -= removed_els_cplx;
179
180 Some(token)
181 }
182
183 fn insert_repeated_elements(
184 &self,
185 value: &mut Vec<T>,
186 cache: &mut VecMutatorCache<M::Cache>,
187 spare_cplx: f64,
188 ) -> Option<UnmutateVecToken<T, M>> {
189 if spare_cplx < 0.01 {
190 return None;
191 }
192
193 let idx = if value.is_empty() {
194 0
195 } else {
196 self.rng.usize(0..value.len())
197 };
198
199 let target_cplx = crate::gen_f64(
200 &self.rng,
201 0.0..crate::gen_f64(
202 &self.rng,
203 0.0..crate::gen_f64(&self.rng, 0.0..crate::gen_f64(&self.rng, 0.0..spare_cplx)),
204 ),
205 );
206 let (min_length, max_length) = self.choose_slice_length(target_cplx);
207 let min_length = min_length.unwrap_or(0);
208
209 let len = if min_length >= max_length {
210 min_length
211 } else {
212 self.rng.usize(min_length..max_length)
213 };
214 if len == 0 {
215 return None;
217 }
218 let (el, el_cache) = self.m.random_arbitrary(target_cplx / (len as f64));
221 let el_cplx = self.m.complexity(&el, &el_cache);
222
223 insert_many(value, idx, repeat(el).take(len));
224 insert_many(&mut cache.inner, idx, repeat(el_cache).take(len));
225
226 let added_cplx = el_cplx * (len as f64);
227 cache.sum_cplx += added_cplx;
228
229 let token = UnmutateVecToken::RemoveMany(idx..(idx + len), added_cplx);
230
231 Some(token)
232 }
233
234 fn choose_slice_length(&self, target_cplx: f64) -> (Option<usize>, usize) {
235 let min_cplx_el = self.m.min_complexity();
236
237 let max_len_most_complex = {
239 let overestimated_max_len: f64 = target_cplx / min_cplx_el;
240 let max_len = if overestimated_max_len.is_infinite() {
241 crate::cplxity_to_size(target_cplx)
243 } else {
244 (overestimated_max_len - overestimated_max_len.log2()) as usize
246 };
247 if max_len > 10_000 {
248 target_cplx.trunc() as usize
251 } else {
252 max_len
253 }
254 };
255 let max_cplx_el = self.m.max_complexity();
256 let min_len_most_complex = target_cplx / max_cplx_el - (target_cplx / max_cplx_el).log2();
260
261 let max_len_most_complex = if max_len_most_complex > 10_000 {
264 target_cplx.trunc() as usize
267 } else {
268 max_len_most_complex
269 };
270
271 if !min_len_most_complex.is_finite() {
272 (None, max_len_most_complex)
273 } else {
274 let min_len_most_complex = min_len_most_complex.trunc() as usize;
275 (Some(min_len_most_complex), max_len_most_complex)
276 }
277 }
278
279 fn new_input_with_length_and_complexity(
280 &self,
281 target_len: usize,
282 target_cplx: f64,
283 ) -> (Vec<T>, <Self as Mutator<Vec<T>>>::Cache) {
284 let mut v = Vec::with_capacity(target_len);
286 let mut cache = VecMutatorCache {
287 inner: Vec::with_capacity(target_len),
288 sum_cplx: 0.0,
289 };
290
291 let mut remaining_cplx = target_cplx;
292 for i in 0..target_len {
293 let max_cplx_element = remaining_cplx / ((target_len - i) as f64);
294 let min_cplx_el = self.m.min_complexity();
295 if min_cplx_el >= max_cplx_element {
296 break;
297 }
298 let cplx_element = crate::gen_f64(&self.rng, min_cplx_el..max_cplx_element);
299 let (x, x_cache) = self.m.random_arbitrary(cplx_element);
300 let x_cplx = self.m.complexity(&x, &x_cache);
301 v.push(x);
302 cache.inner.push(x_cache);
303 cache.sum_cplx += x_cplx;
304 remaining_cplx -= x_cplx;
305 }
306 (v, cache)
307 }
308}
309
310impl<T: Clone, M: Mutator<T>> Mutator<Vec<T>> for VecMutator<T, M> {
311 type Cache = VecMutatorCache<M::Cache>;
312 type MutationStep = MutationStep<M::MutationStep>;
313 type ArbitraryStep = bool; type UnmutateToken = UnmutateVecToken<T, M>;
315
316 fn cache_from_value(&self, value: &Vec<T>) -> Self::Cache {
317 let inner: Vec<_> = value.iter().map(|x| self.m.cache_from_value(&x)).collect();
318
319 let sum_cplx = value
320 .iter()
321 .zip(inner.iter())
322 .fold(0.0, |cplx, (v, cache)| cplx + self.m.complexity(&v, cache));
323
324 VecMutatorCache { inner, sum_cplx }
325 }
326
327 fn initial_step_from_value(&self, value: &Vec<T>) -> Self::MutationStep {
328 let inner: Vec<_> = value.iter().map(|x| self.m.initial_step_from_value(&x)).collect();
329 MutationStep { inner, element_step: 0 }
330 }
331
332 fn max_complexity(&self) -> f64 {
333 std::f64::INFINITY
334 }
335
336 fn min_complexity(&self) -> f64 {
337 1.0
338 }
339
340 fn complexity(&self, value: &Vec<T>, cache: &Self::Cache) -> f64 {
341 1.0 + cache.sum_cplx + crate::size_to_cplxity(value.len() + 1)
342 }
343
344 fn ordered_arbitrary(&self, step: &mut Self::ArbitraryStep, max_cplx: f64) -> Option<(Vec<T>, Self::Cache)> {
345 if max_cplx < self.min_complexity() {
346 return None;
347 }
348 if !*step || max_cplx <= 1.0 {
349 *step = true;
350 return Some((<_>::default(), Self::Cache::default()));
351 } else {
352 return Some(self.random_arbitrary(max_cplx));
353 }
354 }
355
356 fn random_arbitrary(&self, max_cplx: f64) -> (Vec<T>, Self::Cache) {
357 let target_cplx = fastrand::f64() * crate::gen_f64(&self.rng, 0.0..max_cplx);
358 let lengths = self.choose_slice_length(target_cplx);
359
360 if lengths.0.is_none() && self.m.max_complexity() < 0.001 {
361 if lengths.1 <= 0 {
365 return (<_>::default(), Self::Cache::default());
366 }
367 assert!(lengths.1 > 0);
368 let len = self.rng.usize(0..lengths.1);
369 let (el, el_cache) = self.m.random_arbitrary(0.0);
370 let v = repeat(el).take(len).collect();
371 let cache = Self::Cache {
372 inner: repeat(el_cache).take(len).collect(),
373 sum_cplx: 0.0,
374 };
375 return (v, cache);
376 }
377 let (min_length, max_length) = (lengths.0.unwrap_or(0), lengths.1);
378
379 let target_len = if min_length >= max_length {
381 min_length
382 } else {
383 self.rng.usize(min_length..max_length)
384 };
385
386 self.new_input_with_length_and_complexity(target_len, target_cplx)
387 }
388
389 fn ordered_mutate(
390 &self,
391 value: &mut Vec<T>,
392 cache: &mut Self::Cache,
393 step: &mut Self::MutationStep,
394 max_cplx: f64,
395 ) -> Option<Self::UnmutateToken> {
396 if max_cplx < self.min_complexity() {
398 return None;
399 }
400 let spare_cplx = max_cplx - self.complexity(value, cache);
401
402 let token = if value.is_empty() || self.rng.usize(0..20) == 0 {
403 match self.rng.usize(0..10) {
405 0..=3 => self.insert_element(value, cache, spare_cplx),
406 4..=7 => self.remove_element(value, cache),
407 8 => self.insert_repeated_elements(value, cache, spare_cplx),
408 9 => self.remove_many_elements(value, cache),
409 _ => unreachable!(),
410 }
411 } else {
412 let idx = step.element_step % value.len();
414 step.element_step += 1;
415 self.mutate_element(value, cache, step, idx, spare_cplx)
416 };
417 if let Some(token) = token {
418 Some(token)
419 } else {
420 Some(self.random_mutate(value, cache, max_cplx))
421 }
422 }
423
424 fn random_mutate(&self, value: &mut Vec<T>, cache: &mut Self::Cache, max_cplx: f64) -> Self::UnmutateToken {
425 let spare_cplx = max_cplx - self.complexity(value, cache);
426
427 if value.is_empty() || self.rng.usize(0..10) == 0 {
428 match self.rng.usize(0..10) {
430 0..=3 => self.insert_element(value, cache, spare_cplx),
431 4..=7 => self.remove_element(value, cache),
432 8 => self.insert_repeated_elements(value, cache, spare_cplx),
433 9 => self.remove_many_elements(value, cache),
434 _ => unreachable!(),
435 }
436 .unwrap_or_else(|| self.random_mutate(value, cache, max_cplx))
437 } else {
438 let idx = self.rng.usize(0..value.len());
440 let el = &mut value[idx];
441 let el_cache = &mut cache.inner[idx];
442
443 let old_el_cplx = self.m.complexity(&el, el_cache);
444 let token = self.m.random_mutate(el, el_cache, spare_cplx + old_el_cplx);
445
446 let new_el_cplx = self.m.complexity(&el, el_cache);
447 cache.sum_cplx += new_el_cplx - old_el_cplx;
448 UnmutateVecToken::Element(idx, token, old_el_cplx - new_el_cplx)
449 }
450 }
451
452 fn unmutate(&self, value: &mut Vec<T>, cache: &mut Self::Cache, t: Self::UnmutateToken) {
453 match t {
454 UnmutateVecToken::Element(idx, inner_t, diff_cplx) => {
455 let el = &mut value[idx];
456 let el_cache = &mut cache.inner[idx];
457 self.m.unmutate(el, el_cache, inner_t);
458 cache.sum_cplx += diff_cplx;
459 }
460 UnmutateVecToken::Insert(idx, el, el_cache) => {
461 cache.sum_cplx += self.m.complexity(&el, &el_cache);
462
463 value.insert(idx, el);
464 cache.inner.insert(idx, el_cache);
465 }
466 UnmutateVecToken::Remove(idx, el_cplx) => {
467 value.remove(idx);
468 cache.inner.remove(idx);
469 cache.sum_cplx -= el_cplx;
470 }
471 UnmutateVecToken::Replace(new_value, new_cache) => {
472 let _ = std::mem::replace(value, new_value);
474 let _ = std::mem::replace(cache, new_cache);
475 }
476 UnmutateVecToken::InsertMany(idx, v, c) => {
477 insert_many(value, idx, v.into_iter());
478 insert_many(&mut cache.inner, idx, c.inner.into_iter());
479 let added_cplx = c.sum_cplx;
480 cache.sum_cplx += added_cplx;
481 }
482 UnmutateVecToken::RemoveMany(range, cplx) => {
483 value.drain(range.clone());
484 cache.inner.drain(range);
485 cache.sum_cplx -= cplx;
486 }
487 UnmutateVecToken::Nothing => {}
488 }
489 }
490}
491
492fn insert_many<T>(v: &mut Vec<T>, idx: usize, iter: impl Iterator<Item = T>) {
493 let moved_slice = v.drain(idx..).collect::<Vec<T>>().into_iter();
494 v.extend(iter);
495 v.extend(moved_slice);
496}