From e7fd8ec7e1f67a0a977f3584fd8a46ea4a7fa54f Mon Sep 17 00:00:00 2001 From: Mitchell M Date: Mon, 10 Jun 2024 12:14:14 -0500 Subject: [PATCH] validation builder additions --- src/validation_builder.rs | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/validation_builder.rs b/src/validation_builder.rs index 569dcf9..43c4514 100644 --- a/src/validation_builder.rs +++ b/src/validation_builder.rs @@ -1,4 +1,4 @@ -use crate::controls::ValidationFn; +use crate::{controls::ValidationFn, FormToolData}; use std::fmt::Display; /// A helper builder that allows you to specify a validation function @@ -8,23 +8,25 @@ use std::fmt::Display; /// closures, but for simple validation function this builder can be helpful /// /// Validations are run in the order that they are called in the builder. -pub struct ValidationBuilder { +pub struct ValidationBuilder { /// The name of the field, for error messages. name: String, + /// The getter function for the field to validate. + field_fn: Box &T + 'static>, /// The functions to be called when validating. functions: Vec Result<(), String> + 'static>>, } -impl Default for ValidationBuilder { - fn default() -> Self { +impl ValidationBuilder { + /// Creates a new empty [`ValidationBuilder`] on the given field. + pub fn for_field(field_fn: impl Fn(&FD) -> &T + 'static) -> Self { ValidationBuilder { name: String::from("Field"), + field_fn: Box::new(field_fn), functions: Vec::new(), } } -} -impl ValidationBuilder { /// The name of the field that is being validated. /// /// This is the name that will be used for error messages. @@ -33,9 +35,19 @@ impl ValidationBuilder { self } + /// Adds a custom validation function. + /// + /// The function should take the value as an argument and return + /// a [`Result<(), String>`], just like any other validation function. + pub fn custom(mut self, f: impl ValidationFn) -> Self { + self.functions.push(Box::new(move |_name, value| f(value))); + self + } + /// Builds the action validation function. - pub fn build(self) -> impl ValidationFn { - move |value| { + pub fn build(self) -> impl ValidationFn { + move |form_data| { + let value = (self.field_fn)(form_data); for f in self.functions.iter() { match f(self.name.as_str(), value) { Ok(()) => {} @@ -47,7 +59,7 @@ impl ValidationBuilder { } } -impl ValidationBuilder { +impl ValidationBuilder { /// Requires the field to not be empty. pub fn required(mut self) -> Self { self.functions.push(Box::new(move |name, value| { @@ -75,7 +87,7 @@ impl ValidationBuilder { /// Requires the field's length to be less than or equal to `min_len`. pub fn max_len(mut self, max_len: usize) -> Self { self.functions.push(Box::new(move |name, value| { - if value.len() < max_len { + if value.len() > max_len { Err(format!("{} must be <= {} characters", name, max_len)) } else { Ok(()) @@ -85,7 +97,7 @@ impl ValidationBuilder { } } -impl + Display + 'static> ValidationBuilder { +impl + Display + 'static> ValidationBuilder { /// Requires the value to be at least `min_value` according to /// `PartialOrd`. pub fn min_value(mut self, min_value: T) -> Self { @@ -113,7 +125,7 @@ impl + Display + 'static> ValidationBuilder { } } -impl + Display + 'static> ValidationBuilder { +impl + Display + 'static> ValidationBuilder { /// Requires the field to be in the provided whitelist. pub fn whitelist(mut self, whitelist: Vec) -> Self { self.functions.push(Box::new(move |name, value| {