diff options
| author | Vincent Prouillet | 2020-06-09 21:34:50 +0200 |
|---|---|---|
| committer | GitHub | 2020-06-09 21:34:50 +0200 |
| commit | ed5fab36d7f0cb8313dd13464f6f9bfe2bafcf05 (patch) | |
| tree | f26f55834b833eba14a0e5ed1cce22bb45f946a4 | |
| parent | e052be5fdac051d005ab0e93c1016e4e8ac4ee00 (diff) | |
| parent | b83aba922a3d21091b036dcac2840e4ae62e9ebc (diff) | |
| download | validator-ed5fab36d7f0cb8313dd13464f6f9bfe2bafcf05.tar.bz2 | |
Merge pull request #103 from ShadoySV/master
Required validation
| -rw-r--r-- | README.md | 6 | ||||
| -rw-r--r-- | validator/src/lib.rs | 1 | ||||
| -rw-r--r-- | validator/src/validation/mod.rs | 5 | ||||
| -rw-r--r-- | validator/src/validation/required.rs | 5 | ||||
| -rw-r--r-- | validator_derive/src/lib.rs | 7 | ||||
| -rw-r--r-- | validator_derive/src/quoting.rs | 23 | ||||
| -rw-r--r-- | validator_derive/tests/required.rs | 61 |
7 files changed, 108 insertions, 0 deletions
@@ -276,6 +276,12 @@ Tests whether the String has any utf-8 control caracters, fails validation if it To use this validator, you must enable the `unic` feature for the `validator_derive` crate. This validator doesn't take any arguments: `#[validate(non_control_character)]`; +### required +Tests whether the `Option<T>` field is `Some`; + +### required_nested +Tests whether the `Option<T>` field is `Some` and performs validation as `nested` do; + ## Struct level validation Often, some error validation can only be applied when looking at the full struct, here's how it works here: diff --git a/validator/src/lib.rs b/validator/src/lib.rs index 5313c41..deaaca6 100644 --- a/validator/src/lib.rs +++ b/validator/src/lib.rs @@ -14,6 +14,7 @@ pub use validation::non_control_character::validate_non_control_character; #[cfg(feature = "phone")] pub use validation::phone::validate_phone; pub use validation::range::validate_range; +pub use validation::required::validate_required; pub use validation::urls::validate_url; pub use validation::Validator; diff --git a/validator/src/validation/mod.rs b/validator/src/validation/mod.rs index 1675730..a2111d7 100644 --- a/validator/src/validation/mod.rs +++ b/validator/src/validation/mod.rs @@ -10,6 +10,7 @@ pub mod non_control_character; #[cfg(feature = "phone")] pub mod phone; pub mod range; +pub mod required; pub mod urls; /// Contains all the validators that can be used @@ -45,6 +46,8 @@ pub enum Validator { Nested, #[cfg(feature = "unic")] NonControlCharacter, + Required, + RequiredNested, } impl Validator { @@ -65,6 +68,8 @@ impl Validator { Validator::Nested => "nested", #[cfg(feature = "unic")] Validator::NonControlCharacter => "non_control_character", + Validator::Required => "required", + Validator::RequiredNested => "required_nested", } } } diff --git a/validator/src/validation/required.rs b/validator/src/validation/required.rs new file mode 100644 index 0000000..80b06b0 --- /dev/null +++ b/validator/src/validation/required.rs @@ -0,0 +1,5 @@ +/// Validates whether the given Option is Some +#[must_use] +pub fn validate_required<T>(val: &Option<T>) -> bool { + val.is_some() +} diff --git a/validator_derive/src/lib.rs b/validator_derive/src/lib.rs index 6f74202..3244679 100644 --- a/validator_derive/src/lib.rs +++ b/validator_derive/src/lib.rs @@ -287,6 +287,13 @@ fn find_validators_for_field( Validator::NonControlCharacter, )); } + "required" => { + validators.push(FieldValidation::new(Validator::Required)); + } + "required_nested" => { + validators.push(FieldValidation::new(Validator::Required)); + validators.push(FieldValidation::new(Validator::Nested)); + } _ => panic!("Unexpected validator: {:?}", name.get_ident()), } } diff --git a/validator_derive/src/quoting.rs b/validator_derive/src/quoting.rs index dc466ac..a5af288 100644 --- a/validator_derive/src/quoting.rs +++ b/validator_derive/src/quoting.rs @@ -465,6 +465,9 @@ pub fn quote_field_validation( Validator::NonControlCharacter => { validations.push(quote_non_control_character_validation(&field_quoter, validation)) } + Validator::Required | Validator::RequiredNested => { + validations.push(quote_required_validation(&field_quoter, validation)) + } } } @@ -501,3 +504,23 @@ pub fn quote_schema_validation(validation: Option<SchemaValidation>) -> proc_mac quote!() } } + +pub fn quote_required_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, +) -> proc_macro2::TokenStream { + let field_name = &field_quoter.name; + let ident = &field_quoter.ident; + let validator_param = quote!(&self.#ident); + + let quoted_error = quote_error(&validation); + let quoted = quote!( + if !::validator::validate_required(#validator_param) { + #quoted_error + err.add_param(::std::borrow::Cow::from("value"), &#validator_param); + errors.add(#field_name, err); + } + ); + + quoted +} diff --git a/validator_derive/tests/required.rs b/validator_derive/tests/required.rs new file mode 100644 index 0000000..a073f28 --- /dev/null +++ b/validator_derive/tests/required.rs @@ -0,0 +1,61 @@ +#[macro_use] +extern crate validator_derive; + +use serde::Serialize; +use validator::Validate; + +#[derive(Serialize)] +struct ObjectRef { + id: i32, + name: String, +} + +#[derive(Serialize, Validate)] +struct CheckedObjectRef { + #[validate(range(min = 1))] + id: i32, + #[validate(length(min = 1))] + name: String, +} + +#[derive(Validate)] +struct Required { + #[validate(required)] + val: Option<ObjectRef>, +} + +#[derive(Validate)] +struct RequiredNested { + #[validate(required_nested)] + val: Option<CheckedObjectRef>, +} + +#[test] +fn can_validate_required() { + let s = Required { val: Some(ObjectRef { id: 0, name: String::new() }) }; + + assert!(s.validate().is_ok()); +} + +#[test] +fn can_validate_required_nested() { + let s = RequiredNested { + val: Some(CheckedObjectRef { id: 1, name: String::from("Reference representation") }), + }; + + assert!(s.validate().is_ok()); +} + +#[test] +fn none_fails_required() { + let s = Required { val: None }; + + assert!(s.validate().is_err()); +} + +#[test] +fn none_fails_required_nested() { + let s = RequiredNested { val: None }; + + assert!(s.validate().is_err()); +} |
