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()
}
}