From 75121c2fb8b6e19a45ac57af2d9f0af2c1bfd658 Mon Sep 17 00:00:00 2001 From: Olivier Date: Thu, 1 Aug 2024 19:51:50 +0100 Subject: [PATCH] Fix behaviour around Option<>s Signed-off-by: Olivier --- formbeam_derive/src/derive_form.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/formbeam_derive/src/derive_form.rs b/formbeam_derive/src/derive_form.rs index 71ae8c7..199772d 100644 --- a/formbeam_derive/src/derive_form.rs +++ b/formbeam_derive/src/derive_form.rs @@ -318,7 +318,14 @@ fn write_partial_impl_validate( struct FieldInfo { ftype: FieldType, + /// Whether the field is required to be present in the form. + /// This is true unless the type is `Option`. needed: bool, + /// Whether the field needs to be non-empty. By default this is true. + /// If `needed` is false and `need_nonempty` is true, then empty fields will be coerced to `None` instead. + /// If both `needed` and `need_nonempty` are false, then empty fields will be `Some("")` o.e.; only absent fields will be `None`. + /// If both `needed` and `need_nonempty` are true, then empty fields will not be accepted + /// and the `Required` validator is added to the field's info (this matches HTML form semantics). need_nonempty: bool, min_chars: Option, max_chars: Option, @@ -353,7 +360,7 @@ fn write_form_info_for_field(field: &Field, f_info: &FieldInfo) -> TokenStream { let name = field.ident.as_ref().unwrap().to_string(); let mut validators = Vec::new(); - if f_info.need_nonempty { + if f_info.needed && f_info.need_nonempty { validators.push(quote!(::formbeam::FieldValidatorInfo::Required)); } @@ -471,6 +478,16 @@ fn write_partial_impl_form_method( if field_info.needed { converter + } else if field_info.need_nonempty { + // For not-needed fields that must not be empty, + // coerce empty fields into `None` + quote!( + if raw.is_empty() { + None + } else { + Some({#converter}) + } + ) } else { quote!(Some({#converter})) }