in lain/src/mutatable.rs [38:125]
fn grow_vec<T: NewFuzzed + SerializedSize, R: Rng>(
vec: &mut Vec<T>,
mutator: &mut Mutator<R>,
mut max_size: Option<usize>,
) {
let resize_count = VecResizeCount::new_fuzzed(mutator, None);
let mut num_elements = if vec.is_empty() {
mutator.gen_range(1, 9)
} else {
match resize_count {
VecResizeCount::Quarter => vec.len() / 4,
VecResizeCount::Half => vec.len() / 2,
VecResizeCount::ThreeQuarters => vec.len() - (vec.len() / 4),
VecResizeCount::FixedBytes => mutator.gen_range(1, 9),
VecResizeCount::AllBytes => {
mutator.gen_range(1, vec.len() + 1)
}
}
};
// If we were given a size constraint, we need to respect it
if let Some(max_size) = max_size.clone() {
num_elements = min(num_elements, max_size / T::max_default_object_size());
}
if num_elements == 0 {
return;
}
match VecResizeDirection::new_fuzzed(mutator, None) {
VecResizeDirection::FromBeginning => {
// to avoid shifting the the entire vec on every iteration, we will
// instead allocate a new vec, then extend it with the previous one
let mut new_vec = Vec::with_capacity(num_elements);
for _i in 0..num_elements {
let constraints = max_size.map(|max_size| {
let mut c = Constraints::new();
c.max_size(max_size);
c.base_object_size_accounted_for = true;
c
});
let element = T::new_fuzzed(mutator, constraints.as_ref());
if let Some(inner_max_size) = max_size {
// if this element is larger than the size we're allotted,
// then let's just exit
let element_size = element.serialized_size();
if element_size > inner_max_size {
break;
}
max_size = Some(inner_max_size - element_size);
}
new_vec.push(element);
}
new_vec.append(vec);
*vec = new_vec
}
VecResizeDirection::FromEnd => {
for _i in 0..num_elements {
let constraints = max_size.map(|max_size| {
let mut c = Constraints::new();
c.max_size(max_size);
c.base_object_size_accounted_for = true;
c
});
let element = T::new_fuzzed(mutator, constraints.as_ref());
if let Some(inner_max_size) = max_size {
// if this element is larger than the size we're allotted,
// then let's just exit
let element_size = element.serialized_size();
if element_size > inner_max_size {
break;
}
max_size = Some(inner_max_size - element_size);
}
vec.push(element);
}
}
}
}