fn new_fuzzed_unit_enum()

in lain_derive/src/mutations.rs [359:400]


fn new_fuzzed_unit_enum(variants: &[Variant], cont_ident: &syn::Ident) -> TokenStream {
    let (weights, variant_tokens, ignore_chances) =
        new_fuzzed_unit_enum_visitor(variants, cont_ident);

    if variant_tokens.is_empty() {
        return quote! {Default::default()};
    }

    let variant_count = variant_tokens.len();

    quote! {
        use _lain::rand::seq::SliceRandom;
        use _lain::rand::distributions::Distribution;

        static options: [#cont_ident; #variant_count] = [#(#variant_tokens,)*];
        static ignore_chances: [f64; #variant_count] = [#(#ignore_chances,)*];
        static weights: [u64; #variant_count] = [#(#weights,)*];

        _lain::lazy_static::lazy_static! {
            static ref dist: _lain::rand::distributions::WeightedIndex<u64> =
                _lain::rand::distributions::WeightedIndex::new(weights.iter()).unwrap();
        }

        // this shouldn't need to be an option but is because the compiler analysis
        // doesn't think the loop will go at least once
        let mut option: Option<#cont_ident> = None;

        // loop a max of 5 times so we don't infinite loop
        for _i in 0..5 {
            let idx: usize = dist.sample(&mut mutator.rng);
            option = Some(options[idx]);

            let chance = ignore_chances[idx];
            // negate gen_chance since it's a chance to *ignore*
            if chance >= 1.0 || !mutator.gen_chance(chance) {
                break;
            }
        }

        option.unwrap()
    }
}