Explicit handling of whitespace with length
I just started using garde and hit a road block with the length validation. I want to ensure a string is neither too short nor too long. That is simple. Until whitespace is involved.
This is my basic new type struct:
#[derive(Validate)]
#[garde(transparent)]
pub struct UserName(#[garde(length(graphemes, min = 3, max = 256))] String);
I have these two tests for the scenario:
#[test]
fn whitespace_only_names_are_rejected() {
let name = " \t\t\t".to_string();
let result = UserName::new(name);
assert_err!(&result);
assert_eq!("value must not be blank\n", result.unwrap_err().to_string());
}
#[test]
fn empty_string_is_rejected() {
let name = "".to_string();
let result = TenantName::new(name);
assert_err!(&result);
assert_eq!("length is lower than 3\n", result.unwrap_err().to_string());
}
The first test fails with:
assertion failed, expected Err(..), got Ok(UserName(" \t\t\t"))
Okay, the provided string does have a length within the specified range. So I implemented a custom validator:
pub fn is_not_blank(value: &str, _context: &()) -> garde::Result {
if value.trim().is_empty() {
return Err(garde::Error::new("value must not be blank"));
}
Ok(())
}
#[derive(Validate)]
#[garde(transparent)]
pub struct UserName(#[garde(custom(is_not_blank), length(graphemes, min = 3, max = 256))] String);
Now the second test fails with:
assertion `left == right` failed
left: "length is lower than 3\n"
right: "value must not be blank\nlength is lower than 3\n"
It would be great if there was a way to explicitly handle white space in the length check or have one validation supersede another. In this case for example the string is blank so it should only report that right?
garde applies all validations and aggregates all failures in one report. You're using length(graphemes), so it's correctly failing in the first test.
There is an issue open for a mode that would stop on the first failure #1
Your response makes sense. Would it be possible to include an option to treat surrounding whitespace as zero length in the length check? Then one wouldn't have to implement a custom validation for it.
Being able to stop early would also be appreciated.
Would it be possible to include an option to treat surrounding whitespace as zero length in the length check?
I think this is better handled either by rejecting the whitespace using client-side validation, or using a custom validator as you have done. garde is not really intended for use cases where you need to modify the data in some way before validating it.