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. --- README.md | 4 +- validator/src/validation/mod.rs | 4 +- validator/src/validation/range.rs | 44 ++++++++++++++++++++-- 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 ++ 9 files changed, 93 insertions(+), 51 deletions(-) delete mode 100644 validator_derive/tests/compile-fail/range/missing_arg.rs diff --git a/README.md b/README.md index c9bda8d..ce86ead 100644 --- a/README.md +++ b/README.md @@ -179,14 +179,16 @@ Examples: ``` ### range -Tests whether a number is in the given range. `range` takes 2 number arguments: `min` and `max`. +Tests whether a number is in the given range. `range` takes between 1 and 2 number arguments: `min` and `max`. Examples: ```rust #[validate(range(min = "1", max = "10"))] +#[validate(range(min = "1"))] #[validate(range(min = "1", max = "10.8"))] #[validate(range(min = "1.1", max = "10.8"))] +#[validate(range(max = "10.8"))] ``` ### must_match diff --git a/validator/src/validation/mod.rs b/validator/src/validation/mod.rs index 065b27e..95d9b79 100644 --- a/validator/src/validation/mod.rs +++ b/validator/src/validation/mod.rs @@ -27,8 +27,8 @@ pub enum Validator { // No implementation in this crate, it's all in validator_derive Regex(String), Range { - min: f64, - max: f64, + min: Option, + max: Option, }, // Any value that impl HasLen can be validated with Length Length { diff --git a/validator/src/validation/range.rs b/validator/src/validation/range.rs index c643762..a89f707 100644 --- a/validator/src/validation/range.rs +++ b/validator/src/validation/range.rs @@ -5,7 +5,21 @@ use validation::Validator; /// TODO: see if can be generic over the number type pub fn validate_range(range: Validator, val: f64) -> bool { match range { - Validator::Range { min, max } => val >= min && val <= max, + Validator::Range { min, max } => { + if let Some(m) = min { + if val < m { + return false; + } + } + + if let Some(m) = max { + if val > m { + return false; + } + } + + true + } _ => unreachable!(), } } @@ -16,13 +30,37 @@ mod tests { #[test] fn test_validate_range_ok() { - let validator = Validator::Range { min: 0.0, max: 10.0 }; + let validator = Validator::Range { min: Some(0.0), max: Some(10.0) }; assert_eq!(validate_range(validator, 1 as f64), true); } #[test] fn test_validate_range_fail() { - let validator = Validator::Range { min: 0.0, max: 10.0 }; + let validator = Validator::Range { min: Some(0.0), max: Some(10.0) }; assert_eq!(validate_range(validator, 20 as f64), false); } + + #[test] + fn test_validate_range_min_only_valid() { + let validator = Validator::Range { min: Some(10.0), max: None }; + assert_eq!(validate_range(validator, 10.0), true); + } + + #[test] + fn test_validate_range_min_only_invalid() { + let validator = Validator::Range { min: Some(10.0), max: None }; + assert_eq!(validate_range(validator, 9.0), false); + } + + #[test] + fn test_validate_range_max_only_valid() { + let validator = Validator::Range { min: None, max: Some(10.0) }; + assert_eq!(validate_range(validator, 10.0), true); + } + + #[test] + fn test_validate_range_max_only_invalid() { + let validator = Validator::Range { min: None, max: Some(10.0) }; + assert_eq!(validate_range(validator, 11.0), false); + } } 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 f33a34c6ed2d76ce6569a6bc40517ce9a69271d3 Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Wed, 1 May 2019 20:43:37 +0200 Subject: Do not consume self when getting errors Close #65 --- README.md | 4 ++++ validator/Cargo.toml | 2 +- validator/src/types.rs | 13 +++++++------ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index c9bda8d..145c74c 100644 --- a/README.md +++ b/README.md @@ -298,6 +298,10 @@ For example, the following attributes all work: ### validator +#### 0.9.0 (2019/05/01) + +- `ValidationErrors::errors` and `ValidationErrors::field_errors` now use `&self` instead of `self` + #### 0.8.0 (2018/09/19) - Change error type to allow use with nested validation diff --git a/validator/Cargo.toml b/validator/Cargo.toml index f107fbb..dd184a0 100644 --- a/validator/Cargo.toml +++ b/validator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "validator" -version = "0.8.0" +version = "0.9.0" authors = ["Vincent Prouillet HashMap<&'static str, ValidationErrorsKind> { - self.0 + pub fn errors(&self) -> &HashMap<&'static str, ValidationErrorsKind> { + &self.0 } /// Returns a map of only field-level validation errors found for the struct that was validated. - pub fn field_errors(self) -> HashMap<&'static str, Vec> { + pub fn field_errors(&self) -> HashMap<&str, &Vec> { self.0 - .into_iter() + .iter() .filter_map(|(k, v)| { if let ValidationErrorsKind::Field(errors) = v { - Some((k, errors)) + Some((*k, errors)) } else { None } - }).collect() + }) + .collect::>() } pub fn add(&mut self, field: &'static str, error: ValidationError) { -- 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(-) 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 bumping minimum Rust version to 1.34 + #### 0.8.0 (2018/09/19) - Allow nested validation diff --git a/validator/src/types.rs b/validator/src/types.rs index 2d79477..f759ad7 100644 --- a/validator/src/types.rs +++ b/validator/src/types.rs @@ -113,6 +113,11 @@ impl ValidationErrors { &self.0 } + /// Consume the struct, returning the validation errors found + pub fn into_errors(self) -> HashMap<&'static str, ValidationErrorsKind> { + self.0 + } + /// Returns a map of only field-level validation errors found for the struct that was validated. pub fn field_errors(&self) -> HashMap<&str, &Vec> { self.0 diff --git a/validator_derive/src/lit.rs b/validator_derive/src/lit.rs index de0e21e..41deffc 100644 --- a/validator_derive/src/lit.rs +++ b/validator_derive/src/lit.rs @@ -11,8 +11,6 @@ pub fn lit_to_string(lit: &syn::Lit) -> 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 --- README.md | 1 + validator/Cargo.toml | 1 + validator/src/traits.rs | 2 +- validator/src/types.rs | 5 +++-- validator/src/validation/cards.rs | 2 +- validator/src/validation/contains.rs | 2 +- validator/src/validation/email.rs | 2 +- validator/src/validation/ip.rs | 5 +---- validator/src/validation/length.rs | 4 ++-- validator/src/validation/range.rs | 2 +- validator/src/validation/urls.rs | 5 +---- 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 ++++++++++++++------- 17 files changed, 47 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index f3e98d4..fadb9d0 100644 --- a/README.md +++ b/README.md @@ -297,6 +297,7 @@ For example, the following attributes all work: #### 0.9.0 (2019/05/xx) - `ValidationErrors::errors` and `ValidationErrors::field_errors` now use `&self` instead of `self` +- Move to edition 2018 #### 0.8.0 (2018/09/19) diff --git a/validator/Cargo.toml b/validator/Cargo.toml index dd184a0..96e8104 100644 --- a/validator/Cargo.toml +++ b/validator/Cargo.toml @@ -7,6 +7,7 @@ description = "Common validation functions (email, url, length, ...) and trait - homepage = "https://github.com/Keats/validator" repository = "https://github.com/Keats/validator" keywords = ["validation", "api", "validator"] +edition = "2018" [dependencies] url = "1" diff --git a/validator/src/traits.rs b/validator/src/traits.rs index 8d0b129..cf86919 100644 --- a/validator/src/traits.rs +++ b/validator/src/traits.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use std::collections::HashMap; -use types::ValidationErrors; +use crate::types::ValidationErrors; /// Trait to implement if one wants to make the `length` validator /// work for more types diff --git a/validator/src/types.rs b/validator/src/types.rs index f759ad7..09e4c7d 100644 --- a/validator/src/types.rs +++ b/validator/src/types.rs @@ -95,7 +95,8 @@ impl ValidationErrors { .filter_map(|(i, entry)| match entry { Some(ValidationErrorsKind::Struct(errors)) => Some((i, errors)), _ => None, - }).collect::>(); + }) + .collect::>(); if errors.is_empty() { parent @@ -129,7 +130,7 @@ impl ValidationErrors { None } }) - .collect::>() + .collect::>() } pub fn add(&mut self, field: &'static str, error: ValidationError) { diff --git a/validator/src/validation/cards.rs b/validator/src/validation/cards.rs index 19d91ab..8c97694 100644 --- a/validator/src/validation/cards.rs +++ b/validator/src/validation/cards.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use card_validate::Validate as CardValidate; +use crate::card_validate::Validate as CardValidate; pub fn validate_credit_card<'a, T>(card: T) -> bool where diff --git a/validator/src/validation/contains.rs b/validator/src/validation/contains.rs index 8c7b297..ff5d8f2 100644 --- a/validator/src/validation/contains.rs +++ b/validator/src/validation/contains.rs @@ -1,4 +1,4 @@ -use traits::Contains; +use crate::traits::Contains; /// Validates whether the value contains the needle /// The value needs to implement the Contains trait, which is implement on String, str and Hashmap diff --git a/validator/src/validation/email.rs b/validator/src/validation/email.rs index b0b49a3..6ea2fae 100644 --- a/validator/src/validation/email.rs +++ b/validator/src/validation/email.rs @@ -2,7 +2,7 @@ use idna::domain_to_ascii; use regex::Regex; use std::borrow::Cow; -use validation::ip::validate_ip; +use crate::validation::ip::validate_ip; lazy_static! { // Regex from the specs diff --git a/validator/src/validation/ip.rs b/validator/src/validation/ip.rs index dea4260..2026cdc 100644 --- a/validator/src/validation/ip.rs +++ b/validator/src/validation/ip.rs @@ -35,10 +35,7 @@ pub fn validate_ip<'a, T>(val: T) -> bool where T: Into>, { - match IpAddr::from_str(val.into().as_ref()) { - Ok(_) => true, - Err(_) => false, - } + IpAddr::from_str(val.into().as_ref()).is_ok() } #[cfg(test)] diff --git a/validator/src/validation/length.rs b/validator/src/validation/length.rs index 8e6a5a4..58e76ff 100644 --- a/validator/src/validation/length.rs +++ b/validator/src/validation/length.rs @@ -1,5 +1,5 @@ -use traits::HasLen; -use validation::Validator; +use crate::traits::HasLen; +use crate::validation::Validator; /// Validates the length of the value given. /// If the validator has `equal` set, it will ignore any `min` and `max` value. diff --git a/validator/src/validation/range.rs b/validator/src/validation/range.rs index a89f707..a5664fa 100644 --- a/validator/src/validation/range.rs +++ b/validator/src/validation/range.rs @@ -1,4 +1,4 @@ -use validation::Validator; +use crate::validation::Validator; /// Validates that a number is in the given range /// diff --git a/validator/src/validation/urls.rs b/validator/src/validation/urls.rs index 56c3390..1c46c6f 100644 --- a/validator/src/validation/urls.rs +++ b/validator/src/validation/urls.rs @@ -6,10 +6,7 @@ pub fn validate_url<'a, T>(val: T) -> bool where T: Into>, { - match Url::parse(val.into().as_ref()) { - Ok(_) => true, - Err(_) => false, - } + Url::parse(val.into().as_ref()).is_ok() } #[cfg(test)] 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 081c30300a7c4a07e708f491011bf7a6790f3889 Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Wed, 1 May 2019 22:06:55 +0200 Subject: Apparently attr_literals was stable in 1.30 --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fadb9d0..875f066 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@ Macros 1.1 custom derive to simplify struct validation inspired by [marshmallow](http://marshmallow.readthedocs.io/en/latest/) and [Django validators](https://docs.djangoproject.com/en/1.10/ref/validators/). + +It requires Rust 1.30. + A short example: ```rust @@ -327,7 +330,7 @@ For example, the following attributes all work: #### 0.9.0 (2019/05/xx) -- Use literals in macros now that it's stable -> bumping minimum Rust version to 1.34 +- Use literals in macros now that it's stable -> bumping minimum Rust version to 1.30 #### 0.8.0 (2018/09/19) -- 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(-) 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