fn mutate()

in lain/src/mutatable.rs [354:411]


    fn mutate<R: Rng>(
        &mut self,
        mutator: &mut Mutator<R>,
        constraints: Option<&Constraints<Self::RangeType>>,
    ) {
        let mut constraints = constraints.and_then(|c| {
            if c.max_size.is_none() {
                None
            } else {
                let mut new_constraints = Constraints::new();
                new_constraints.base_object_size_accounted_for = c.base_object_size_accounted_for;
                new_constraints.max_size = c.max_size;

                Some(new_constraints)
            }
        });

        // Check if we can even mutate this item
        if let Some(max_size) = constraints.as_ref().map(|c| c.max_size).flatten().clone() {
            if T::min_nonzero_elements_size() < max_size {
                return;
            }
        }

        for item in self.iter_mut() {
            let parent_constraints = constraints.clone();
            if let Some(constraints) = constraints.as_mut() {
                if let Some(max_size) = constraints.max_size.as_mut() {
                    let prev_size = item.serialized_size();

                    if T::max_default_object_size() > *max_size {
                        let prev_obj = item.clone();

                        T::mutate(item, mutator, parent_constraints.as_ref());
                        if item.serialized_size() > *max_size {
                            // the mutated object is too large --
                            *item = prev_obj
                        } else {
                            continue;
                        }
                    } else {
                        T::mutate(item, mutator, parent_constraints.as_ref());
                    }

                    let new_size = item.serialized_size();

                    let delta = (new_size as isize) - (prev_size as isize);
                    *max_size = (*max_size as isize - delta) as usize;
                }
            } else {
                T::mutate(item, mutator, constraints.as_ref());
            }

            if mutator.should_early_bail_mutation() {
                return;
            }
        }
    }