-
Notifications
You must be signed in to change notification settings - Fork 158
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
Rewrite derive macro implementation #262
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Veeery nice
validator_derive/src/lib.rs
Outdated
min: Option<u64>, | ||
max: Option<u64>, | ||
equal: Option<u64>, | ||
message: Option<String>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's missing code
as well. It is much nicer and waaaay less code, very nice.
Random thought: is it possible to parse all the attributes into a hashmap rather than a struct? I'm wondering if there would be a way for a user to register functions with validator and use them on the derive as if they were built-in. Maybe it's not worth it though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a map
attribute for the macro that let's you specify a function to run after parsing the attributes like
#[derive(FromMeta)]
#[darling(map = "to_hashmap")]
struct Custom {
par_1: Option<Expr>,
par_2: Option<Expr>,
par_3: Option<Expr>,
#[darling(skip)]
hashmap: HashMap<String, Expr>
}
fn to_hashmap(custom: Custom) -> HashMap<String, Expr> {}
I have to try it out, I'm not sure if this will work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's only worth it if we have some kind of register of fns, and I'm not sure how to configure where to look that up... Maybe let's not worry about it for now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very well. I'll implement the rest of the macro and get it up and running and possibly passing the tests and then worry about everything else.
validator/src/validation/length.rs
Outdated
@@ -12,7 +12,7 @@ use indexmap::{IndexMap, IndexSet}; | |||
/// If you apply it on String, don't forget that the length can be different | |||
/// from the number of visual characters for Unicode | |||
#[must_use] | |||
pub fn validate_length<T: ValidateLength>( | |||
pub fn validate_length<T: ValidateLength<u64>>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function is kind of useless now that there's the trait I think. Also casting the min
, max
and equal
values to u64
might lead to issues when you for example cast a negative i32
to u64
. So I thought to add a generic, so that the length
and all the parameters have to be the same type to compare them without runtime errors or weird casting issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove it then I think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of the functions will be used in the macro from the validator crate so they can be removed unless they're used anywhere else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep they can be removed now that we have traits
I've rewritten the custom validation a bit. If you want arguments for your function you can specify them like: #[derive(Validate)]
struct TestStruct {
#[validate(custom(
function = "valid_reference_with_lifetime",
arg = "len: i64",
arg = "something: bool",
arg = "name: String"
))]
value: String,
}
let test = TestStruct { name: "asdfg".to_string() };
let res = test.validate(TestStructArgs { len: 123, something: false, name: "Something".into() }); Also the TestStructArgs::build().len(123).something(false).name("Something").build() How does this look? I'm now wrangling with lifetimes so for now you can only pass values and not references. Should I continue with this or go back to tuples like it's now? |
The UI tests now pass. I had to put them behind a feature to avoid running them on anything other than |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I admit i went a little fast on the review but i left some comments
@@ -58,6 +58,22 @@ impl ValidationErrors { | |||
} | |||
} | |||
|
|||
pub fn merge_self( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is that? I am thinking we probably also want to maybe re-think the errors interface in another PR to be easier to use/more intuitive
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had some trouble adding errors on nested validations so I whipped up this function. And I agree, the errors API should be redone.
@@ -1,5 +1,5 @@ | |||
error: Invalid attribute #[validate] on field `s`: unknown argument `eq` for validator `length` (it only has `min`, `max`, `equal`) | |||
--> $DIR/unknown_arg.rs:5:23 | |||
error: Unknown field: `eq`. Did you mean `equal`? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's an unknown attribute/argument, not an unknown field
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an error from darling
. I think it defaults to field for everything?
panic!("Expected list validation errors"); | ||
} | ||
} | ||
// Skip this test for now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can it be enabled again?
@@ -1,5 +1,5 @@ | |||
error: Invalid schema level validation: `function` is required | |||
--> $DIR/missing_function.rs:4:12 | |||
error: Missing field `function` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again attribute/argument
@@ -114,81 +117,103 @@ fn can_fail_schema_fn_validation() { | |||
assert_eq!(errs["__all__"][0].code, "meh"); | |||
} | |||
|
|||
// #[test] | |||
// fn can_fail_multiple_schema_fn_validation() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can that test be enabled?
Just a couple more tests that are currently commented out, can I merge and uncomment them or is there a reason they are commented out? |
Sorry for the wait, forgot about this. No the tests don't pass currently if you uncomment them I think. I was thinking gating the |
ah it's all related to that feature? You can just remove it for now then |
Ok I removed the original field name from serde test and added back multiple schema validation. I think that makes everything? Also the documentation should be updated, this PR is a breaking change after all. |
Let's update the docs later, we might have more things. Thanks a lot! |
* Rewrite derive macro implementation * Add better error handling * Add new types to validator macro * Add empty files in tokens module * Removed i32 tests for length * Fix email to pass tests * fix length validation trait to work with u64 only * Add credit card token generation to macro * Add url token generation to macro * Add ValidateIp trait * Add ip token generation to macro * Remove unneeded import * Export ValidateIp trait from main crate * Add tests for ValidateIp macro * Add non control character token generation to macro * Add test for range with enums * Add range token generation to macro * Add required token generation to macro * Fix ValidationErrors merge function * Move contains trait to contains.rs * Add ValidateContains trait and fix tests * Add ValidateContains and DoesNotContain traits to macro * Add must match token generation to macro * Add regex token generation * Add custom validation token generation to macro * Add custom validation with arguments to macro * Add custom validation with args with contexts * Add custom validation recommit * Fix custom validation to work without lifetimes * Change custom validation to use closures * Fix tests for custom validation * Change custom validation to implement FnOnce and add tests * Remove code used for experementing * Remove unneeded code * Remove unused imports * Add schema with arguments and fix tests * Impl ValidateLength trait for Option types * Fix impls for ValidateRange * Fix duplicate use statements * Fix tests and add Option impls for Contains * Implement ValidateUrl traits for specific types * Implement ValidateEmail traits for specific types * Fix some tests and warnings * Add regex trait for validation * Fix to pass tests in validator lib * Fix range validation trait to pass tests * Update and remove unneeded dependencies * Add ValidateNested trait * Fix custom and nested validation * Fix Regex validator to work with OnceCell and OnceLock * Fix derive macro to support all the arguments * Remove unneeded functions and fix tests * Remove validator_types crate and fix tests * Update CI workflow * Fix custom to be used in nested validations * Fix custom validation to use context * Add custom nested validation with args test * Fix validation to use Validation trait * Remove conflicting trait * Fixed tests and remove ValidateContext trait * Fix nested validation * Fix custom args test * Add `nest_all_fields` attribute * Add better error handling and start fixing UI tests * Pass almost all tests * Add skip_on_field_errors attribute to schema * Remove rust beta channel from workflow * Use proc_macro_error instead of darling diagnostics feature * Conditionally run UI tests * Fix ci.yml * Fix ci.yml * Remove UI test for wrong type on range * Change trait impls to be consistent * Run cargo clippy --fix * Replace if else with match * Remove cargo-expand leftovers * Replace underscore with `#[allow(unused)]` * Add support for multiple schema validations * Remove serde original field name test
* Rewrite derive macro implementation * Add better error handling * Add new types to validator macro * Add empty files in tokens module * Removed i32 tests for length * Fix email to pass tests * fix length validation trait to work with u64 only * Add credit card token generation to macro * Add url token generation to macro * Add ValidateIp trait * Add ip token generation to macro * Remove unneeded import * Export ValidateIp trait from main crate * Add tests for ValidateIp macro * Add non control character token generation to macro * Add test for range with enums * Add range token generation to macro * Add required token generation to macro * Fix ValidationErrors merge function * Move contains trait to contains.rs * Add ValidateContains trait and fix tests * Add ValidateContains and DoesNotContain traits to macro * Add must match token generation to macro * Add regex token generation * Add custom validation token generation to macro * Add custom validation with arguments to macro * Add custom validation with args with contexts * Add custom validation recommit * Fix custom validation to work without lifetimes * Change custom validation to use closures * Fix tests for custom validation * Change custom validation to implement FnOnce and add tests * Remove code used for experementing * Remove unneeded code * Remove unused imports * Add schema with arguments and fix tests * Impl ValidateLength trait for Option types * Fix impls for ValidateRange * Fix duplicate use statements * Fix tests and add Option impls for Contains * Implement ValidateUrl traits for specific types * Implement ValidateEmail traits for specific types * Fix some tests and warnings * Add regex trait for validation * Fix to pass tests in validator lib * Fix range validation trait to pass tests * Update and remove unneeded dependencies * Add ValidateNested trait * Fix custom and nested validation * Fix Regex validator to work with OnceCell and OnceLock * Fix derive macro to support all the arguments * Remove unneeded functions and fix tests * Remove validator_types crate and fix tests * Update CI workflow * Fix custom to be used in nested validations * Fix custom validation to use context * Add custom nested validation with args test * Fix validation to use Validation trait * Remove conflicting trait * Fixed tests and remove ValidateContext trait * Fix nested validation * Fix custom args test * Add `nest_all_fields` attribute * Add better error handling and start fixing UI tests * Pass almost all tests * Add skip_on_field_errors attribute to schema * Remove rust beta channel from workflow * Use proc_macro_error instead of darling diagnostics feature * Conditionally run UI tests * Fix ci.yml * Fix ci.yml * Remove UI test for wrong type on range * Change trait impls to be consistent * Run cargo clippy --fix * Replace if else with match * Remove cargo-expand leftovers * Replace underscore with `#[allow(unused)]` * Add support for multiple schema validations * Remove serde original field name test
A proposal on rewriting the derive macro implementation using the
darling
crate. It massively simplifies the macro. The only two validators I got up an working are thelength
andemail
just for show. Also there is no error handling for now.Also I had to upgrade
syn
version to2
asdarling
would work with version1
.