Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for const args in custom validators #221

Open
Samuel-B-D opened this issue Jul 6, 2022 · 1 comment
Open

Support for const args in custom validators #221

Samuel-B-D opened this issue Jul 6, 2022 · 1 comment

Comments

@Samuel-B-D
Copy link

Samuel-B-D commented Jul 6, 2022

I feel like it would be useful to have the ability to have const args for the validator.
Example scenario / use:

use validator::{Validate, ValidateArgs, ValidationError};

fn vec_string_max_len(value: &Vec<String>, const_arg: u64) -> Result<(), ValidationError> {
    for s in value.iter() {
        if s.length() > arg {
            return Err(ValidationError::new("String too long"));
        }
    }
    Ok(())
}

#[derive(Debug, Validate)]
struct TestStruct {
    #[validate(length(max = 10), custom(function = "vec_string_max_len", const_arg = "64"))]
    many_strings: Vec<String>,
}

let test_struct: TestStruct = [...]
test_struct.validate().is_ok();
// many_strings contain at most 10 strings, and each string is at most 64 characters long

That way, such validation can be defined in the model and don't need to be passed around each time you validate.
As of now, unless I am missing something, I don't really see a way to make such a validator in a way which doesn't require either passing along data in validate_args(...) or writing a validate function specific to that field only.

The suggested syntax above is to mirror the syntax of the current validate-time args, I don't really like it but that's a start 😅

@Samuel-B-D Samuel-B-D changed the title Support for litteral args in custom validators Support for const args in custom validators Jul 6, 2022
@prk3
Copy link

prk3 commented Aug 5, 2022

You can achieve this now by using const generics. It will work only with ints and bools though.

use validator::{Validate, ValidateArgs, ValidationError};

fn vec_string_max_len<const N: usize>(value: &Vec<String>) -> Result<(), ValidationError> {
    for s in value.iter() {
        if s.len() > N {
            return Err(ValidationError::new("String too long"));
        }
    }
    Ok(())
}

#[derive(Debug, Validate)]
struct TestStruct {
    #[validate(length(max = 10), custom(function = "vec_string_max_len::<64>"))]
    many_strings: Vec<String>,
}

fn main() {
    let test_struct = TestStruct {
        many_strings: vec!["hello".into(), "world".into()],
    };
    test_struct.validate().is_ok();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants