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

Use traits for validation rules #205

Open
tqwewe opened this issue Apr 21, 2022 · 6 comments
Open

Use traits for validation rules #205

tqwewe opened this issue Apr 21, 2022 · 6 comments

Comments

@tqwewe
Copy link

tqwewe commented Apr 21, 2022

When trying to derive Validate on a struct, it seems like the derive macro filters what types you can use manually.

Wouldn't it make more sense to instead have a trait for each validation rule, allowing users to implement validation rules for their custom types?

For example, this does not work:

#[derive(Validate)]
struct Data {
  #[validate(length(min = 5, message = "must have 5+ characters"))]
  name: Mutable<String>,
}

But I'd like to be able to do something like this to resolve it:

impl validator::rules::ValidateLength for Mutable<String> {
  fn validate_length(&self, min: Option<u64>, max: Option<u64>) -> Result<(), ValidationError> {
    // ...
  }
}
@Keats
Copy link
Owner

Keats commented Apr 23, 2022

How would you the trait look like? I don't think it would work without variadic generics

@tqwewe
Copy link
Author

tqwewe commented Apr 24, 2022

I'm not sure why generics may be needed.
I was imagining something like:

trait ValidateLength {
  fn validate_length(&self, min: Option<u64>, max: Option<u64>) -> bool;
}

trait ValidateEmail {
  fn validate_email(&self) -> bool;
}

trait ValidateUrl {
  fn validate_url(&self) -> bool;
}

trait ValidateContains {
  fn validate_contains(&self, s: &str) -> bool;
}

...

And these traits would be implemented for some standard types where appropriate, eg impl ValidateEmail for String, etc.

@Keats
Copy link
Owner

Keats commented Apr 24, 2022

Yeah my bad I was thinking the wrong thing yesterday. This would be nice but how do you envision it working in the proc macro? You still need to search for patterns in the fields types to know whether they are supported or try to di it anyway and get compilation errors in invisible generated code which isn't great.

@tqwewe
Copy link
Author

tqwewe commented Apr 25, 2022

I don't think you need to do any kind of checking of the types in the proc macro, just let Rust tell the user "ValidateEmail is not supported for type Foo". Proc macro would just expand to <Foo as validator:: ValidateEmail >::validate_email(), and Rust would error if it's not implemented for the type.

@Keats
Copy link
Owner

Keats commented Apr 25, 2022

If the error message is not too bad it could work. It's a pretty huge change though so it would need to come as a PR so it can be tested properly.

@pintariching
Copy link
Contributor

I have opened #225 to see if I'm going in the right direction. For now I've just implemented if for length`

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

No branches or pull requests

3 participants