fn new_fuzzed()

in lain/src/new_fuzzed.rs [160:294]


    fn new_fuzzed<R: Rng>(
        mutator: &mut Mutator<R>,
        constraints: Option<&Constraints<Self::RangeType>>,
    ) -> Vec<T> {
        const MAX_NUM_ELEMENTS: usize = 0x1000;

        let mut min: Self::RangeType;
        let mut max: Self::RangeType;
        let weight: Weighted;
        let max_size: Option<usize>;
        let mut used_size: usize = 0;
        let mut output: Vec<T>;

        trace!(
            "Generating random Vec with constraints: {:#X?}",
            constraints
        );

        if T::max_default_object_size() == 0 {
            warn!("Size of element in vec is 0... returning early");
            return vec![];
        }

        // if no min/max were supplied, we'll take a conservative approach of 64 elements
        match constraints {
            Some(constraints) => {
                min = constraints.min.unwrap_or(0);
                max = constraints.max.unwrap_or(MAX_NUM_ELEMENTS);

                if min != max {
                    if min != 0 && mutator.gen_chance(crate::mutator::CHANCE_TO_IGNORE_MIN_MAX) {
                        min = 0;
                    }

                    if constraints.max.is_some()
                        && mutator.gen_chance(crate::mutator::CHANCE_TO_IGNORE_MIN_MAX)
                    {
                        // we just hope this doesn't overflow.
                        max = constraints.max.unwrap() * 2;
                    }
                }

                weight = constraints.weighted;

                max_size = constraints.max_size;
                if let Some(max_size) = constraints.max_size {
                    max = cmp::min(max, max_size / T::max_default_object_size());
                }
            }
            None => {
                min = 0;
                max = MAX_NUM_ELEMENTS;
                max_size = None;
                weight = Weighted::None;
            }
        }

        if max == 0 {
            return vec![];
        }

        if min > max {
            min = 0;
        }

        // If min == max, that means the user probably wants this to be exactly that many elements.
        let num_elements: usize = if min == max {
            min
        } else {
            mutator.gen_weighted_range(min, max, weight)
        };

        output = Vec::with_capacity(num_elements);

        let should_reuse_array_item =
            mutator.gen_chance(crate::mutator::CHANCE_TO_REPEAT_ARRAY_VALUE);

        if should_reuse_array_item {
            let element: T = if let Some(ref max_size) = max_size {
                T::new_fuzzed(
                    mutator,
                    Some(
                        &Constraints::new()
                            .max_size(max_size - used_size)
                            .set_base_size_accounted_for(),
                    ),
                )
            } else {
                T::new_fuzzed(mutator, None)
            };

            let element_serialized_size = element.serialized_size();

            for _i in 0..num_elements {
                if let Some(ref max_size) = max_size {
                    if used_size + element_serialized_size > *max_size {
                        break;
                    } else {
                        used_size += element_serialized_size;
                    }
                }

                output.push(element.clone());
            }
        } else {
            for _i in 0..num_elements {
                let element: T = if let Some(ref max_size) = max_size {
                    T::new_fuzzed(
                        mutator,
                        Some(
                            &Constraints::new()
                                .max_size(max_size - used_size)
                                .set_base_size_accounted_for(),
                        ),
                    )
                } else {
                    T::new_fuzzed(mutator, None)
                };

                let element_serialized_size = element.serialized_size();

                if let Some(ref max_size) = max_size {
                    if used_size + element_serialized_size > *max_size {
                        break;
                    } else {
                        used_size += element_serialized_size;
                    }
                }

                output.push(element);
            }
        }

        output
    }