-
-
Notifications
You must be signed in to change notification settings - Fork 795
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 #[serde(validate = "function")]
for container, compatible with validator
crate
#2891
base: master
Are you sure you want to change the base?
Conversation
…ble with validator crate
Co-authored-by: Mingun <[email protected]>
And I notice that the |
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'll need to read up on the issue discussions and the extent to which we may want to simplify validator
crate support
The most user friendly API should like that #[derive(Deserialize)]
#[serde(validator)]
struct ValidatorDemo {
#[validate(email)]
mail: String,
} However it needs to expand into follows, assume the #[derive(validator::Validate, Deserialize)]
#[serde(validate = "validator::Validate::validate")]
struct ValidatorDemo {
#[validate(email)]
mail: String,
} And I think it is impossible to make the Deserialize |
I think it's ok for |
Great, I will do that |
Now we have two ways to use #[derive(validator::Validate, Deserialize)]
#[serde(validate = "validator::Validate::validate")]
struct ValidateStruct {
#[validate(email)]
mail: String,
}
#[derive(validator::Validate, Deserialize)]
#[serde(validator)]
struct ValidatorStruct {
#[validate(email)]
mail: String,
} And it will send error message when both |
#[serde(validate = "validator::Validate::validate")] | ||
#[serde(validator)] |
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 not really wrong to have two validation schemes running at the same time. serde(validate = "..")
could be specified twice, too (add a test?)
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.
You mean user can define a list of validation schemes?
I think that's a good idea.
What the advantage of using Because Rust already supports using paths in attributes, why you choosed using string for |
.iter() | ||
.map(|validate| { | ||
quote! { | ||
#validate(&body).map_err(#serde::de::Error::custom)?; |
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.
Probably it is better to use From
trait here and below?
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.
You mean the signature of validation should be fn <E: serde::de::Error>(&T) -> Result<(), impl Into<E>>
?
In this case, if we want to call #[serde(validate = "validator::Validate::validate")]
to use validator
, the only way is to add follow code within serde
, since Rust only allow local impl for trait E
impl<E: serde::de::Error> From<validator::ValidationErrors> for E { }
It will introduce a new dependence for serde
, I don't know if we can do that
Well, there are only serde::de::Error::cutom
and serde::de::Error::invalid_value
that are suitable for validation, I think just use serde::de::Error::cutom
is a good approach :)
Hi @Mingun, thank you for your review.
Considering the user interface consistency, I just reuse the |
Hi, I am wondering is there any suggestions for this PR? So that I can modify under that. |
This PR aims to sovle #939, #642
The basic idea is only specify validate function in container attribute, since it is the most general way.
One can directly use
validator::Validate::validate
as validation function, so it is not necessary to have field validator inserde
.The
Error
needs to beimpl Display
, to convert it byserde::de::Error::custom
.For general usage, one can use arbitrary
fn (&T) -> Result<(), impl Display>
function to validate.And for
validator
user, there is no extra overhead to do validate.The full unit-test & demo see here.
I am glad to write documents if this idea looks good to you :)