diff options
Diffstat (limited to 'validator_derive')
22 files changed, 184 insertions, 150 deletions
diff --git a/validator_derive/Cargo.toml b/validator_derive/Cargo.toml index 52aad39..e8e50aa 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 <prouillet.vincent@gmail.com"]  license = "MIT"  description = "Macros 1.1 implementation of #[derive(Validate)]" @@ -19,8 +19,8 @@ card = ["validator/card"]  syn = { version = "0.15", features = ["extra-traits"] }  quote = "0.6"  proc-macro2 = "0.4" -if_chain = "0" -validator = { version = "0.8", path = "../validator"} +if_chain = "1" +validator = { version = "0.9", path = "../validator"}  regex = "1"  lazy_static = "1" 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<Option<f64>>",  ]; -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<Vec<") @@ -89,8 +89,8 @@ pub fn assert_has_len(field_name: String, field_type: &String) {      }  } -pub fn assert_has_range(field_name: String, field_type: &String) { -    if !NUMBER_TYPES.contains(&field_type.as_ref()) { +pub fn assert_has_range(field_name: String, field_type: &str) { +    if !NUMBER_TYPES.contains(&field_type) {          panic!(              "Validator `range` can only be used on number types but found `{}` for field `{}`",              field_type, field_name diff --git a/validator_derive/src/lib.rs b/validator_derive/src/lib.rs index 0647a7d..f3796b4 100644 --- a/validator_derive/src/lib.rs +++ b/validator_derive/src/lib.rs @@ -420,8 +420,8 @@ fn find_original_field_name(meta_items: &Vec<&syn::NestedMeta>) -> Option<String      let mut original_name = None;      for meta_item in meta_items { -        match *meta_item { -            &syn::NestedMeta::Meta(ref item) => 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/lit.rs b/validator_derive/src/lit.rs index 14e3f56..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<String> {  pub fn lit_to_int(lit: &syn::Lit) -> Option<u64> {      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::<u64>().unwrap()),          _ => None,      }  } @@ -21,8 +19,6 @@ pub fn lit_to_float(lit: &syn::Lit) -> Option<f64> {      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::<f64>().unwrap()),          _ => None,      }  } @@ -30,12 +26,6 @@ pub fn lit_to_float(lit: &syn::Lit) -> Option<f64> {  pub fn lit_to_bool(lit: &syn::Lit) -> Option<bool> {      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,      }  } @@ -46,3 +36,10 @@ pub fn option_u64_to_tokens(opt: Option<u64>) -> proc_macro2::TokenStream {          None => quote!(::std::option::Option::None),      }  } + +pub fn option_f64_to_tokens(opt: Option<f64>) -> 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..b94962c 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 @@ -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 @@ -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..5f42d7b 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<syn::NestedMeta>,  ) -> 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_none() && max.is_none() { +        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/complex.rs b/validator_derive/tests/complex.rs index 7826a49..305b0ce 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,7 +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(); +    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); @@ -167,13 +168,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<Option<&'a str>>, -        #[validate(range(min = "1", max = "100"))] +        #[validate(range(min = 1, max = 100))]          age: Option<Option<usize>>, -        #[validate(range(min = "1", max = "10"))] +        #[validate(range(min = 1, max = 10))]          range: Option<usize>,          #[validate(email)]          email: Option<&'a str>, @@ -213,17 +214,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<String>, -        #[validate(length(min = "1", max = "10"))] +        #[validate(length(min = 1, max = 10))]          address: Option<Option<String>>, -        #[validate(length(min = "1", max = "10"))] +        #[validate(length(min = 1, max = 10))]          ids: Option<Vec<usize>>, -        #[validate(length(min = "1", max = "10"))] +        #[validate(length(min = 1, max = 10))]          opt_ids: Option<Option<Vec<usize>>>, -        #[validate(range(min = "1", max = "100"))] +        #[validate(range(min = 1, max = 100))]          age: Option<Option<usize>>, -        #[validate(range(min = "1", max = "10"))] +        #[validate(range(min = 1, max = 10))]          range: Option<usize>,          #[validate(email)]          email: Option<String>, @@ -281,13 +282,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<String>, -        #[validate(length(min = "1", max = "10"))] +        #[validate(length(min = 1, max = 10))]          address: Option<Option<String>>, -        #[validate(range(min = "1", max = "100"))] +        #[validate(range(min = 1, max = 100))]          age: Option<Option<usize>>, -        #[validate(range(min = "1", max = "10"))] +        #[validate(range(min = 1, max = 10))]          range: Option<usize>,      } @@ -304,5 +305,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..781f01d 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<Child>,  }  #[derive(Debug, Validate, Serialize)]  struct Child { -    #[validate(length(min = "1"))] +    #[validate(length(min = 1))]      value: String,  } @@ -71,7 +71,8 @@ fn failed_validation_points_to_original_field_names() {      let res = root.validate();      assert!(res.is_err()); -    let errs = res.unwrap_err().errors(); +    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"] { @@ -118,7 +119,8 @@ fn test_can_validate_option_fields_without_lifetime() {      let res = instance.validate();      assert!(res.is_err()); -    let errs = res.unwrap_err().errors(); +    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"] { @@ -151,7 +153,8 @@ fn test_can_validate_option_fields_with_lifetime() {      let res = instance.validate();      assert!(res.is_err()); -    let errs = res.unwrap_err().errors(); +    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"] { @@ -191,7 +194,8 @@ fn test_can_validate_vector_fields() {      let res = instance.validate();      assert!(res.is_err()); -    let errs = res.unwrap_err().errors(); +    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"] { @@ -228,7 +232,8 @@ fn test_field_validations_take_priority_over_nested_validations() {      let res = instance.validate();      assert!(res.is_err()); -    let errs = res.unwrap_err().errors(); +    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"] { @@ -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);              } @@ -343,5 +350,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/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<u8>, +    #[validate(range(min = 18.0))] +    s10: Option<u8>, +    #[validate(range(max = 18.0))] +    s11: Option<u8>,  }  fn main() {} 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");  | 
