From 6e8effdaa2b47f4056a00d301a9e7a5a1a2fd8dc Mon Sep 17 00:00:00 2001 From: Caroline Glassberg-Powell Date: Sun, 28 Apr 2019 18:45:40 +0100 Subject: Issue #69: Change `range` to require only one arg Currently range is hard-coded to take both max and min. This is unhelpful in cases where we may only want to check one of the bounds. Update so that it behaves more like the `length` validator and can take either max or min, as well as both. Also ensure that at least one of them is supplied. --- validator_derive/src/lit.rs | 7 ++++ validator_derive/src/quoting.rs | 21 +++++++++-- validator_derive/src/validation.rs | 43 +++++++++------------- .../tests/compile-fail/range/missing_arg.rs | 15 -------- .../tests/compile-fail/range/no_args.rs | 2 +- validator_derive/tests/run-pass/range.rs | 4 ++ 6 files changed, 47 insertions(+), 45 deletions(-) delete mode 100644 validator_derive/tests/compile-fail/range/missing_arg.rs (limited to 'validator_derive') diff --git a/validator_derive/src/lit.rs b/validator_derive/src/lit.rs index 14e3f56..de0e21e 100644 --- a/validator_derive/src/lit.rs +++ b/validator_derive/src/lit.rs @@ -46,3 +46,10 @@ pub fn option_u64_to_tokens(opt: Option) -> proc_macro2::TokenStream { None => quote!(::std::option::Option::None), } } + +pub fn option_f64_to_tokens(opt: Option) -> proc_macro2::TokenStream { + match opt { + Some(ref t) => quote!(::std::option::Option::Some(#t)), + None => quote!(::std::option::Option::None), + } +} diff --git a/validator_derive/src/quoting.rs b/validator_derive/src/quoting.rs index f94d8fc..fa97623 100644 --- a/validator_derive/src/quoting.rs +++ b/validator_derive/src/quoting.rs @@ -3,7 +3,7 @@ use syn; use validator::Validator; use asserts::{COW_TYPE, NUMBER_TYPES}; -use lit::option_u64_to_tokens; +use lit::{option_f64_to_tokens, option_u64_to_tokens}; use validation::{FieldValidation, SchemaValidation}; /// Pass around all the information needed for creating a validation @@ -183,12 +183,25 @@ pub fn quote_range_validation( let quoted_ident = field_quoter.quote_validator_param(); if let Validator::Range { min, max } = validation.validator { + // Can't interpolate None + let min_tokens = option_f64_to_tokens(min); + let max_tokens = option_f64_to_tokens(max); + + let min_err_param_quoted = if let Some(v) = min { + quote!(err.add_param(::std::borrow::Cow::from("min"), &#v);) + } else { + quote!() + }; + let max_err_param_quoted = if let Some(v) = max { + quote!(err.add_param(::std::borrow::Cow::from("max"), &#v);) + } else { + quote!() + }; + let quoted_error = quote_error(&validation); - let min_err_param_quoted = quote!(err.add_param(::std::borrow::Cow::from("min"), &#min);); - let max_err_param_quoted = quote!(err.add_param(::std::borrow::Cow::from("max"), &#max);); let quoted = quote!( if !::validator::validate_range( - ::validator::Validator::Range {min: #min, max: #max}, + ::validator::Validator::Range {min: #min_tokens, max: #max_tokens}, #quoted_ident as f64 ) { #quoted_error diff --git a/validator_derive/src/validation.rs b/validator_derive/src/validation.rs index a9762db..d9ad5a5 100644 --- a/validator_derive/src/validation.rs +++ b/validator_derive/src/validation.rs @@ -95,8 +95,8 @@ pub fn extract_range_validation( field: String, meta_items: &Vec, ) -> FieldValidation { - let mut min = 0.0; - let mut max = 0.0; + let mut min = None; + let mut max = None; let (message, code) = extract_message_and_code("range", &field, meta_items); @@ -104,45 +104,38 @@ pub fn extract_range_validation( panic!("Invalid attribute #[validate] on field `{}`: {}", field, msg); }; - // whether it has both `min` and `max` - let mut has_min = false; - let mut has_max = false; - for meta_item in meta_items { match *meta_item { syn::NestedMeta::Meta(ref item) => match *item { - syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) => match ident - .to_string() - .as_ref() - { - "message" | "code" => continue, - "min" => { - min = match lit_to_float(lit) { - Some(s) => s, + syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) => { + match ident.to_string().as_ref() { + "message" | "code" => continue, + "min" => { + min = match lit_to_float(lit) { + Some(s) => Some(s), None => error("invalid argument type for `min` of `range` validator: only integers are allowed") }; - has_min = true; - } - "max" => { - max = match lit_to_float(lit) { - Some(s) => s, + } + "max" => { + max = match lit_to_float(lit) { + Some(s) => Some(s), None => error("invalid argument type for `max` of `range` validator: only integers are allowed") }; - has_max = true; - } - v => error(&format!( + } + v => error(&format!( "unknown argument `{}` for validator `range` (it only has `min`, `max`)", v )), - }, + } + } _ => panic!("unexpected item {:?} while parsing `range` validator", item), }, _ => unreachable!(), } } - if !has_min || !has_max { - error("Validator `range` requires 2 arguments: `min` and `max`"); + if !min.is_some() && !max.is_some() { + error("Validator `range` requires at least 1 argument out of `min` and `max`"); } let validator = Validator::Range { min, max }; diff --git a/validator_derive/tests/compile-fail/range/missing_arg.rs b/validator_derive/tests/compile-fail/range/missing_arg.rs deleted file mode 100644 index 3aed1f0..0000000 --- a/validator_derive/tests/compile-fail/range/missing_arg.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![feature(attr_literals)] - -#[macro_use] extern crate validator_derive; -extern crate validator; -use validator::Validate; - -#[derive(Validate)] -//~^ ERROR: proc-macro derive panicked -//~^^ HELP: Invalid attribute #[validate] on field `s`: Validator `range` requires 2 arguments: `min` and `max` -struct Test { - #[validate(range(min = 2.0))] - s: i32, -} - -fn main() {} diff --git a/validator_derive/tests/compile-fail/range/no_args.rs b/validator_derive/tests/compile-fail/range/no_args.rs index c2bdd03..b097b0a 100644 --- a/validator_derive/tests/compile-fail/range/no_args.rs +++ b/validator_derive/tests/compile-fail/range/no_args.rs @@ -4,7 +4,7 @@ use validator::Validate; #[derive(Validate)] //~^ ERROR: proc-macro derive panicked -//~^^ HELP: Invalid attribute #[validate] on field `s`: Validator `range` requires 2 arguments: `min` and `max` +//~^^ HELP: Invalid attribute #[validate] on field `s`: Validator `range` requires at least 1 argument out of `min` and `max` struct Test { #[validate(range())] s: i32, diff --git a/validator_derive/tests/run-pass/range.rs b/validator_derive/tests/run-pass/range.rs index e35f3df..520dd64 100644 --- a/validator_derive/tests/run-pass/range.rs +++ b/validator_derive/tests/run-pass/range.rs @@ -24,6 +24,10 @@ struct Test { s8: u8, #[validate(range(min = 18.0, max = 22))] s9: Option, + #[validate(range(min = 18.0))] + s10: Option, + #[validate(range(max = 18.0))] + s11: Option, } fn main() {} -- cgit v1.2.3 From 798988018920144535f2bd5aa93a8d3f4423b42c Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Wed, 1 May 2019 20:49:43 +0200 Subject: Update deps of validator_derive --- validator_derive/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'validator_derive') diff --git a/validator_derive/Cargo.toml b/validator_derive/Cargo.toml index 52aad39..f985e1d 100644 --- a/validator_derive/Cargo.toml +++ b/validator_derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "validator_derive" -version = "0.8.0" +version = "0.9.0" authors = ["Vincent Prouillet Option { pub fn lit_to_int(lit: &syn::Lit) -> Option { match *lit { syn::Lit::Int(ref s) => Some(s.value()), - // TODO: remove when attr_literals is stable - syn::Lit::Str(ref s) => Some(s.value().parse::().unwrap()), _ => None, } } @@ -21,8 +19,6 @@ pub fn lit_to_float(lit: &syn::Lit) -> Option { match *lit { syn::Lit::Float(ref s) => Some(s.value()), syn::Lit::Int(ref s) => Some(s.value() as f64), - // TODO: remove when attr_literals is stable - syn::Lit::Str(ref s) => Some(s.value().parse::().unwrap()), _ => None, } } @@ -30,12 +26,6 @@ pub fn lit_to_float(lit: &syn::Lit) -> Option { pub fn lit_to_bool(lit: &syn::Lit) -> Option { match *lit { syn::Lit::Bool(ref s) => Some(s.value), - // TODO: remove when attr_literals is stable - syn::Lit::Str(ref s) => if s.value() == "true" { - Some(true) - } else { - Some(false) - }, _ => None, } } diff --git a/validator_derive/tests/complex.rs b/validator_derive/tests/complex.rs index 7826a49..974fdad 100644 --- a/validator_derive/tests/complex.rs +++ b/validator_derive/tests/complex.rs @@ -29,16 +29,16 @@ fn validate_signup(data: &SignupData) -> Result<(), ValidationError> { } #[derive(Debug, Validate, Deserialize)] -#[validate(schema(function = "validate_signup", skip_on_field_errors = "false"))] +#[validate(schema(function = "validate_signup", skip_on_field_errors = false))] struct SignupData { #[validate(email)] mail: String, #[validate(url)] site: String, - #[validate(length(min = "1"), custom = "validate_unique_username")] + #[validate(length(min = 1), custom = "validate_unique_username")] #[serde(rename = "firstName")] first_name: String, - #[validate(range(min = "18", max = "20"))] + #[validate(range(min = 18, max = 20))] age: u32, #[validate] phone: Phone, @@ -58,13 +58,13 @@ struct Phone { struct Card { #[validate(credit_card)] number: String, - #[validate(range(min = "100", max = "9999"))] + #[validate(range(min = 100, max = 9999))] cvv: u32, } #[derive(Debug, Validate, Deserialize)] struct Preference { - #[validate(length(min = "4"))] + #[validate(length(min = 4))] name: String, value: bool, } @@ -98,8 +98,8 @@ fn failed_validation_points_to_original_field_name() { let res = signup.validate(); // println!("{}", serde_json::to_string(&res).unwrap()); assert!(res.is_err()); - let errs = res.unwrap_err().errors(); - assert!(errs.contains_key("firstName")); + let err = res.unwrap_err(); +let errs = err.errors();assert!(errs.contains_key("firstName")); if let ValidationErrorsKind::Field(ref err) = errs["firstName"] { assert_eq!(err.len(), 1); assert_eq!(err[0].code, "length"); @@ -167,13 +167,13 @@ fn test_can_validate_option_fields_with_lifetime() { #[derive(Debug, Validate)] struct PutStruct<'a> { - #[validate(length(min = "1", max = "10"))] + #[validate(length(min = 1, max = 10))] name: Option<&'a str>, - #[validate(length(min = "1", max = "10"))] + #[validate(length(min = 1, max = 10))] address: Option>, - #[validate(range(min = "1", max = "100"))] + #[validate(range(min = 1, max = 100))] age: Option>, - #[validate(range(min = "1", max = "10"))] + #[validate(range(min = 1, max = 10))] range: Option, #[validate(email)] email: Option<&'a str>, @@ -213,17 +213,17 @@ fn test_can_validate_option_fields_without_lifetime() { #[derive(Debug, Validate)] struct PutStruct { - #[validate(length(min = "1", max = "10"))] + #[validate(length(min = 1, max = 10))] name: Option, - #[validate(length(min = "1", max = "10"))] + #[validate(length(min = 1, max = 10))] address: Option>, - #[validate(length(min = "1", max = "10"))] + #[validate(length(min = 1, max = 10))] ids: Option>, - #[validate(length(min = "1", max = "10"))] + #[validate(length(min = 1, max = 10))] opt_ids: Option>>, - #[validate(range(min = "1", max = "100"))] + #[validate(range(min = 1, max = 100))] age: Option>, - #[validate(range(min = "1", max = "10"))] + #[validate(range(min = 1, max = 10))] range: Option, #[validate(email)] email: Option, @@ -281,13 +281,13 @@ fn test_works_with_question_mark_operator() { fn test_works_with_none_values() { #[derive(Debug, Validate)] struct PutStruct { - #[validate(length(min = "1", max = "10"))] + #[validate(length(min = 1, max = 10))] name: Option, - #[validate(length(min = "1", max = "10"))] + #[validate(length(min = 1, max = 10))] address: Option>, - #[validate(range(min = "1", max = "100"))] + #[validate(range(min = 1, max = 100))] age: Option>, - #[validate(range(min = "1", max = "10"))] + #[validate(range(min = 1, max = 10))] range: Option, } @@ -304,5 +304,5 @@ where F: FnOnce(HashMap<&'static str, ValidationErrorsKind>), { let errors = *errors.clone(); - f(errors.errors()); + f(errors.errors().clone()); } diff --git a/validator_derive/tests/contains.rs b/validator_derive/tests/contains.rs index 1fd568d..77880a5 100644 --- a/validator_derive/tests/contains.rs +++ b/validator_derive/tests/contains.rs @@ -28,7 +28,8 @@ fn value_not_containing_needle_fails_validation() { let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "contains"); @@ -46,7 +47,8 @@ fn can_specify_code_for_contains() { let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "oops"); @@ -62,7 +64,8 @@ fn can_specify_message_for_contains() { let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].clone().message.unwrap(), "oops"); diff --git a/validator_derive/tests/credit_card.rs b/validator_derive/tests/credit_card.rs index d212c48..ca84657 100644 --- a/validator_derive/tests/credit_card.rs +++ b/validator_derive/tests/credit_card.rs @@ -30,7 +30,8 @@ fn bad_credit_card_fails_validation() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "credit_card"); @@ -48,7 +49,8 @@ fn can_specify_code_for_credit_card() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "oops"); @@ -65,7 +67,8 @@ fn can_specify_message_for_credit_card() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].clone().message.unwrap(), "oops"); diff --git a/validator_derive/tests/custom.rs b/validator_derive/tests/custom.rs index c13853d..d39cbbe 100644 --- a/validator_derive/tests/custom.rs +++ b/validator_derive/tests/custom.rs @@ -36,7 +36,8 @@ fn can_fail_custom_fn_validation() { let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "meh"); @@ -53,7 +54,8 @@ fn can_specify_message_for_custom_fn() { let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].clone().message.unwrap(), "oops"); diff --git a/validator_derive/tests/email.rs b/validator_derive/tests/email.rs index 665f0da..3c3f499 100644 --- a/validator_derive/tests/email.rs +++ b/validator_derive/tests/email.rs @@ -28,7 +28,8 @@ fn bad_email_fails_validation() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "email"); @@ -45,7 +46,8 @@ fn can_specify_code_for_email() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "oops"); @@ -61,7 +63,8 @@ fn can_specify_message_for_email() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].clone().message.unwrap(), "oops"); diff --git a/validator_derive/tests/length.rs b/validator_derive/tests/length.rs index 6ad6272..df4a87c 100644 --- a/validator_derive/tests/length.rs +++ b/validator_derive/tests/length.rs @@ -8,7 +8,7 @@ use validator::Validate; fn can_validate_length_ok() { #[derive(Debug, Validate)] struct TestStruct { - #[validate(length(min = "5", max = "10"))] + #[validate(length(min = 5, max = 10))] val: String, } @@ -21,14 +21,15 @@ fn can_validate_length_ok() { fn value_out_of_length_fails_validation() { #[derive(Debug, Validate)] struct TestStruct { - #[validate(length(min = "5", max = "10"))] + #[validate(length(min = 5, max = 10))] val: String, } let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "length"); @@ -41,13 +42,14 @@ fn value_out_of_length_fails_validation() { fn can_specify_code_for_length() { #[derive(Debug, Validate)] struct TestStruct { - #[validate(length(min = "5", max = "10", code = "oops"))] + #[validate(length(min = 5, max = 10, code = "oops"))] val: String, } let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "oops"); @@ -57,13 +59,14 @@ fn can_specify_code_for_length() { fn can_specify_message_for_length() { #[derive(Debug, Validate)] struct TestStruct { - #[validate(length(min = "5", max = "10", message = "oops"))] + #[validate(length(min = 5, max = 10, message = "oops"))] val: String, } let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].clone().message.unwrap(), "oops"); diff --git a/validator_derive/tests/must_match.rs b/validator_derive/tests/must_match.rs index 32b3016..9b7bb10 100644 --- a/validator_derive/tests/must_match.rs +++ b/validator_derive/tests/must_match.rs @@ -31,7 +31,8 @@ fn not_matching_fails_validation() { let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "must_match"); @@ -50,7 +51,8 @@ fn can_specify_code_for_must_match() { let s = TestStruct { val: "bob".to_string(), val2: "bobb".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "oops"); @@ -67,7 +69,8 @@ fn can_specify_message_for_must_match() { let s = TestStruct { val: "bob".to_string(), val2: "bobb".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].clone().message.unwrap(), "oops"); diff --git a/validator_derive/tests/nested.rs b/validator_derive/tests/nested.rs index a95b0ef..9e3e57f 100644 --- a/validator_derive/tests/nested.rs +++ b/validator_derive/tests/nested.rs @@ -11,7 +11,7 @@ use validator::{ #[derive(Debug, Validate)] struct Root<'a> { - #[validate(length(min = "1"))] + #[validate(length(min = 1))] value: String, #[validate] @@ -20,7 +20,7 @@ struct Root<'a> { #[derive(Debug, Validate)] struct A { - #[validate(length(min = "1"))] + #[validate(length(min = 1))] value: String, #[validate] @@ -29,7 +29,7 @@ struct A { #[derive(Debug, Validate)] struct B { - #[validate(length(min = "1"))] + #[validate(length(min = 1))] value: String, } @@ -42,13 +42,13 @@ struct ParentWithOptionalChild { #[derive(Debug, Validate)] struct ParentWithVectorOfChildren { #[validate] - #[validate(length(min = "1"))] + #[validate(length(min = 1))] child: Vec, } #[derive(Debug, Validate, Serialize)] struct Child { - #[validate(length(min = "1"))] + #[validate(length(min = 1))] value: String, } @@ -71,8 +71,8 @@ fn failed_validation_points_to_original_field_names() { let res = root.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().errors(); - assert_eq!(errs.len(), 2); + let err = res.unwrap_err(); +let errs = err.errors();assert_eq!(errs.len(), 2); assert!(errs.contains_key("value")); if let ValidationErrorsKind::Field(ref errs) = errs["value"] { assert_eq!(errs.len(), 1); @@ -118,8 +118,8 @@ fn test_can_validate_option_fields_without_lifetime() { let res = instance.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().errors(); - assert_eq!(errs.len(), 1); + let err = res.unwrap_err(); +let errs = err.errors();assert_eq!(errs.len(), 1); assert!(errs.contains_key("child")); if let ValidationErrorsKind::Struct(ref errs) = errs["child"] { unwrap_map(errs, |errs| { @@ -151,8 +151,8 @@ fn test_can_validate_option_fields_with_lifetime() { let res = instance.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().errors(); - assert_eq!(errs.len(), 1); + let err = res.unwrap_err(); +let errs = err.errors();assert_eq!(errs.len(), 1); assert!(errs.contains_key("child")); if let ValidationErrorsKind::Struct(ref errs) = errs["child"] { unwrap_map(errs, |errs| { @@ -191,8 +191,8 @@ fn test_can_validate_vector_fields() { let res = instance.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().errors(); - assert_eq!(errs.len(), 1); + let err = res.unwrap_err(); +let errs = err.errors();assert_eq!(errs.len(), 1); assert!(errs.contains_key("child")); if let ValidationErrorsKind::List(ref errs) = errs["child"] { assert!(errs.contains_key(&1)); @@ -228,8 +228,8 @@ fn test_field_validations_take_priority_over_nested_validations() { let res = instance.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().errors(); - assert_eq!(errs.len(), 1); + let err = res.unwrap_err(); +let errs = err.errors();assert_eq!(errs.len(), 1); assert!(errs.contains_key("child")); if let ValidationErrorsKind::Field(ref errs) = errs["child"] { assert_eq!(errs.len(), 1); @@ -343,5 +343,5 @@ where F: FnOnce(HashMap<&'static str, ValidationErrorsKind>), { let errors = *errors.clone(); - f(errors.errors()); + f(errors.errors().clone()); } diff --git a/validator_derive/tests/phone.rs b/validator_derive/tests/phone.rs index a87d037..b692a8f 100644 --- a/validator_derive/tests/phone.rs +++ b/validator_derive/tests/phone.rs @@ -30,7 +30,8 @@ fn bad_phone_fails_validation() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "phone"); @@ -47,7 +48,8 @@ fn can_specify_code_for_phone() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "oops"); @@ -65,7 +67,8 @@ fn can_specify_message_for_phone() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].clone().message.unwrap(), "oops"); diff --git a/validator_derive/tests/range.rs b/validator_derive/tests/range.rs index 4f38f18..869510a 100644 --- a/validator_derive/tests/range.rs +++ b/validator_derive/tests/range.rs @@ -8,7 +8,7 @@ use validator::Validate; fn can_validate_range_ok() { #[derive(Debug, Validate)] struct TestStruct { - #[validate(range(min = "5", max = "10"))] + #[validate(range(min = 5, max = 10))] val: usize, } @@ -21,14 +21,15 @@ fn can_validate_range_ok() { fn value_out_of_range_fails_validation() { #[derive(Debug, Validate)] struct TestStruct { - #[validate(range(min = "5", max = "10"))] + #[validate(range(min = 5, max = 10))] val: usize, } let s = TestStruct { val: 11 }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "range"); @@ -38,13 +39,14 @@ fn value_out_of_range_fails_validation() { fn can_specify_code_for_range() { #[derive(Debug, Validate)] struct TestStruct { - #[validate(range(min = "5", max = "10", code = "oops"))] + #[validate(range(min = 5, max = 10, code = "oops"))] val: usize, } let s = TestStruct { val: 11 }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "oops"); @@ -57,13 +59,14 @@ fn can_specify_code_for_range() { fn can_specify_message_for_range() { #[derive(Debug, Validate)] struct TestStruct { - #[validate(range(min = "5", max = "10", message = "oops"))] + #[validate(range(min = 5, max = 10, message = "oops"))] val: usize, } let s = TestStruct { val: 1 }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].clone().message.unwrap(), "oops"); diff --git a/validator_derive/tests/regex.rs b/validator_derive/tests/regex.rs index a6b9e68..7e3dfc5 100644 --- a/validator_derive/tests/regex.rs +++ b/validator_derive/tests/regex.rs @@ -36,7 +36,8 @@ fn bad_value_for_regex_fails_validation() { let s = TestStruct { val: "2".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "regex"); @@ -53,7 +54,8 @@ fn can_specify_code_for_regex() { let s = TestStruct { val: "2".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "oops"); @@ -69,7 +71,8 @@ fn can_specify_message_for_regex() { let s = TestStruct { val: "2".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].clone().message.unwrap(), "oops"); diff --git a/validator_derive/tests/schema.rs b/validator_derive/tests/schema.rs index b45f3a1..3a45711 100644 --- a/validator_derive/tests/schema.rs +++ b/validator_derive/tests/schema.rs @@ -36,7 +36,8 @@ fn can_fail_schema_fn_validation() { let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("__all__")); assert_eq!(errs["__all__"].len(), 1); assert_eq!(errs["__all__"][0].code, "meh"); @@ -56,7 +57,8 @@ fn can_specify_message_for_schema_fn() { let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("__all__")); assert_eq!(errs["__all__"].len(), 1); assert_eq!(errs["__all__"][0].clone().message.unwrap(), "oops"); @@ -68,10 +70,10 @@ fn can_choose_to_run_schema_validation_even_after_field_errors() { Err(ValidationError::new("meh")) } #[derive(Debug, Validate)] - #[validate(schema(function = "invalid_schema_fn", skip_on_field_errors = "false"))] + #[validate(schema(function = "invalid_schema_fn", skip_on_field_errors = false))] struct TestStruct { val: String, - #[validate(range(min = "1", max = "10"))] + #[validate(range(min = 1, max = 10))] num: usize, } @@ -79,7 +81,8 @@ fn can_choose_to_run_schema_validation_even_after_field_errors() { let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("__all__")); assert_eq!(errs["__all__"].len(), 1); assert_eq!(errs["__all__"][0].clone().code, "meh"); diff --git a/validator_derive/tests/url.rs b/validator_derive/tests/url.rs index 0ac3cb1..3b867b9 100644 --- a/validator_derive/tests/url.rs +++ b/validator_derive/tests/url.rs @@ -28,7 +28,9 @@ fn bad_url_fails_validation() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "url"); @@ -44,7 +46,9 @@ fn can_specify_code_for_url() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].code, "oops"); @@ -61,7 +65,8 @@ fn can_specify_message_for_url() { let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); - let errs = res.unwrap_err().field_errors(); + let err = res.unwrap_err(); + let errs = err.field_errors(); assert!(errs.contains_key("val")); assert_eq!(errs["val"].len(), 1); assert_eq!(errs["val"][0].clone().message.unwrap(), "oops"); -- cgit v1.2.3 From 467298db852205329758f89d7c2f2639b61ad66a Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Wed, 1 May 2019 22:03:17 +0200 Subject: Cargo fmt + edition 2018 for validator --- validator_derive/src/asserts.rs | 10 +++++----- validator_derive/src/lib.rs | 4 ++-- validator_derive/src/quoting.rs | 18 +++++++++--------- validator_derive/src/validation.rs | 2 +- validator_derive/tests/complex.rs | 3 ++- validator_derive/tests/nested.rs | 21 ++++++++++++++------- 6 files changed, 33 insertions(+), 25 deletions(-) (limited to 'validator_derive') diff --git a/validator_derive/src/asserts.rs b/validator_derive/src/asserts.rs index 1a8dfff..a5892a8 100644 --- a/validator_derive/src/asserts.rs +++ b/validator_derive/src/asserts.rs @@ -43,7 +43,7 @@ pub static NUMBER_TYPES: [&'static str; 36] = [ "Option>", ]; -pub fn assert_string_type(name: &str, field_type: &String) { +pub fn assert_string_type(name: &str, field_type: &str) { if field_type != "String" && field_type != "&str" && !COW_TYPE.is_match(field_type) @@ -59,7 +59,7 @@ pub fn assert_string_type(name: &str, field_type: &String) { } } -pub fn assert_type_matches(field_name: String, field_type: &String, field_type2: Option<&String>) { +pub fn assert_type_matches(field_name: String, field_type: &str, field_type2: Option<&String>) { if let Some(t2) = field_type2 { if field_type != t2 { panic!("Invalid argument for `must_match` validator of field `{}`: types of field can't match", field_name); @@ -69,7 +69,7 @@ pub fn assert_type_matches(field_name: String, field_type: &String, field_type2: } } -pub fn assert_has_len(field_name: String, field_type: &String) { +pub fn assert_has_len(field_name: String, field_type: &str) { if field_type != "String" && !field_type.starts_with("Vec<") && !field_type.starts_with("Option) -> Option match *item { + match **meta_item { + syn::NestedMeta::Meta(ref item) => match *item { syn::Meta::Word(_) => continue, syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) => { if ident == "rename" { diff --git a/validator_derive/src/quoting.rs b/validator_derive/src/quoting.rs index fa97623..b94962c 100644 --- a/validator_derive/src/quoting.rs +++ b/validator_derive/src/quoting.rs @@ -32,7 +32,7 @@ impl FieldQuoter { quote!(#ident) } else if COW_TYPE.is_match(&self._type.as_ref()) { quote!(self.#ident.as_ref()) - } else if self._type.starts_with("&") || NUMBER_TYPES.contains(&self._type.as_ref()) { + } else if self._type.starts_with('&') || NUMBER_TYPES.contains(&self._type.as_ref()) { quote!(self.#ident) } else { quote!(&self.#ident) @@ -92,14 +92,14 @@ impl FieldQuoter { let field_name = &self.name; if self._type.starts_with("Vec<") { return quote!( - if !::validator::ValidationErrors::has_error(&result, #field_name) { - let results: Vec<_> = self.#field_ident.iter().map(|#field_ident| { - let mut result = ::std::result::Result::Ok(()); - #tokens - result - }).collect(); - result = ::validator::ValidationErrors::merge_all(result, #field_name, results); - }); + if !::validator::ValidationErrors::has_error(&result, #field_name) { + let results: Vec<_> = self.#field_ident.iter().map(|#field_ident| { + let mut result = ::std::result::Result::Ok(()); + #tokens + result + }).collect(); + result = ::validator::ValidationErrors::merge_all(result, #field_name, results); + }); } tokens diff --git a/validator_derive/src/validation.rs b/validator_derive/src/validation.rs index d9ad5a5..5f42d7b 100644 --- a/validator_derive/src/validation.rs +++ b/validator_derive/src/validation.rs @@ -134,7 +134,7 @@ pub fn extract_range_validation( } } - if !min.is_some() && !max.is_some() { + if min.is_none() && max.is_none() { error("Validator `range` requires at least 1 argument out of `min` and `max`"); } diff --git a/validator_derive/tests/complex.rs b/validator_derive/tests/complex.rs index 974fdad..305b0ce 100644 --- a/validator_derive/tests/complex.rs +++ b/validator_derive/tests/complex.rs @@ -99,7 +99,8 @@ fn failed_validation_points_to_original_field_name() { // println!("{}", serde_json::to_string(&res).unwrap()); assert!(res.is_err()); let err = res.unwrap_err(); -let errs = err.errors();assert!(errs.contains_key("firstName")); + let errs = err.errors(); + assert!(errs.contains_key("firstName")); if let ValidationErrorsKind::Field(ref err) = errs["firstName"] { assert_eq!(err.len(), 1); assert_eq!(err[0].code, "length"); diff --git a/validator_derive/tests/nested.rs b/validator_derive/tests/nested.rs index 9e3e57f..781f01d 100644 --- a/validator_derive/tests/nested.rs +++ b/validator_derive/tests/nested.rs @@ -72,7 +72,8 @@ fn failed_validation_points_to_original_field_names() { let res = root.validate(); assert!(res.is_err()); let err = res.unwrap_err(); -let errs = err.errors();assert_eq!(errs.len(), 2); + let errs = err.errors(); + assert_eq!(errs.len(), 2); assert!(errs.contains_key("value")); if let ValidationErrorsKind::Field(ref errs) = errs["value"] { assert_eq!(errs.len(), 1); @@ -119,7 +120,8 @@ fn test_can_validate_option_fields_without_lifetime() { let res = instance.validate(); assert!(res.is_err()); let err = res.unwrap_err(); -let errs = err.errors();assert_eq!(errs.len(), 1); + let errs = err.errors(); + assert_eq!(errs.len(), 1); assert!(errs.contains_key("child")); if let ValidationErrorsKind::Struct(ref errs) = errs["child"] { unwrap_map(errs, |errs| { @@ -152,7 +154,8 @@ fn test_can_validate_option_fields_with_lifetime() { let res = instance.validate(); assert!(res.is_err()); let err = res.unwrap_err(); -let errs = err.errors();assert_eq!(errs.len(), 1); + let errs = err.errors(); + assert_eq!(errs.len(), 1); assert!(errs.contains_key("child")); if let ValidationErrorsKind::Struct(ref errs) = errs["child"] { unwrap_map(errs, |errs| { @@ -192,7 +195,8 @@ fn test_can_validate_vector_fields() { let res = instance.validate(); assert!(res.is_err()); let err = res.unwrap_err(); -let errs = err.errors();assert_eq!(errs.len(), 1); + let errs = err.errors(); + assert_eq!(errs.len(), 1); assert!(errs.contains_key("child")); if let ValidationErrorsKind::List(ref errs) = errs["child"] { assert!(errs.contains_key(&1)); @@ -229,7 +233,8 @@ fn test_field_validations_take_priority_over_nested_validations() { let res = instance.validate(); assert!(res.is_err()); let err = res.unwrap_err(); -let errs = err.errors();assert_eq!(errs.len(), 1); + let errs = err.errors(); + assert_eq!(errs.len(), 1); assert!(errs.contains_key("child")); if let ValidationErrorsKind::Field(ref errs) = errs["child"] { assert_eq!(errs.len(), 1); @@ -275,7 +280,8 @@ fn test_field_validation_errors_replaced_with_nested_validations_fails() { let mut result = Ok(()); result = ValidationErrors::merge(result, "child", child.validate()); result - }).collect(); + }) + .collect(); result = ValidationErrors::merge_all(result, "child", results); } result @@ -313,7 +319,8 @@ fn test_field_validations_evaluated_after_nested_validations_fails() { let mut result = Ok(()); result = ValidationErrors::merge(result, "child", child.validate()); result - }).collect(); + }) + .collect(); result = ValidationErrors::merge_all(result, "child", results); } -- cgit v1.2.3 From 0877c01f9a1bf5bcda3e3b235730f4d09982d8d2 Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Sat, 13 Jul 2019 16:35:37 +0200 Subject: Update if_chain --- validator_derive/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'validator_derive') diff --git a/validator_derive/Cargo.toml b/validator_derive/Cargo.toml index f985e1d..e8e50aa 100644 --- a/validator_derive/Cargo.toml +++ b/validator_derive/Cargo.toml @@ -19,7 +19,7 @@ card = ["validator/card"] syn = { version = "0.15", features = ["extra-traits"] } quote = "0.6" proc-macro2 = "0.4" -if_chain = "0" +if_chain = "1" validator = { version = "0.9", path = "../validator"} regex = "1" lazy_static = "1" -- cgit v1.2.3