fn struct_field_constraints()

in lain_derive/src/mutations.rs [478:524]


fn struct_field_constraints(field: &Field, for_mutation: bool) -> TokenStream {
    let attrs = &field.attrs;
    if !for_mutation {
        if attrs.ignore() || (attrs.initializer().is_some() && !attrs.ignore_chance().is_some()) {
            return TokenStream::new();
        }
    }

    if attrs.min().is_some() || attrs.max().is_some() || attrs.bits().is_some() {
        let min: TokenStream;
        let max: TokenStream;

        if let Some(bits) = attrs.bits() {
            // TODO: maybe refactor attributes so that they can retain original span
            let bitfield_max = syn::LitInt::new(
                2_u64.pow(bits as u32),
                syn::IntSuffix::None,
                Span::call_site(),
            );
            max = quote! {Some(#bitfield_max)};
            min = quote! {Some(0)};
        } else {
            min = option_to_tokens(attrs.min());
            max = option_to_tokens(attrs.max());
        }

        let weight_to = attrs.weight_to().unwrap_or(&attr::WeightTo::None);
        quote! {
            let mut constraints = Constraints::new();
            constraints.min = #min;
            constraints.max = #max;
            constraints.weighted = #weight_to;
            constraints.max_size = max_size;
            constraints.base_object_size_accounted_for = true;
            let constraints = Some(constraints);
        }
    } else {
        quote! {
            let constraints = max_size.as_ref().and_then(|m| {
                let mut c = Constraints::new();
                c.base_object_size_accounted_for = true;
                c.max_size(*m);
                Some(c)
            });
        }
    }
}