diff options
| author | Vincent Prouillet | 2017-01-19 13:35:05 +0900 | 
|---|---|---|
| committer | Vincent Prouillet | 2017-01-19 13:38:47 +0900 | 
| commit | c8fb03bdd7391fc7b9fdc56efcc55a5eec08e19c (patch) | |
| tree | 9e11068da6092c5f072ea95a6265e5391adeca75 /validator_derive | |
| parent | 696e4273173033a6b1d488416c5433d9c49eb8e9 (diff) | |
| download | validator-c8fb03bdd7391fc7b9fdc56efcc55a5eec08e19c.tar.bz2 | |
Validators work for Option<TYPE>
Diffstat (limited to 'validator_derive')
| -rw-r--r-- | validator_derive/src/lib.rs | 32 | ||||
| -rw-r--r-- | validator_derive/tests/test_derive.rs | 45 | 
2 files changed, 63 insertions, 14 deletions
| diff --git a/validator_derive/src/lib.rs b/validator_derive/src/lib.rs index 177f315..0ad26a9 100644 --- a/validator_derive/src/lib.rs +++ b/validator_derive/src/lib.rs @@ -71,10 +71,12 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {            quote!(&self.#field_ident)          };          // same but for the ident used in a if let block -        let optional_validator_param = if field_name.starts_with("Option<&") { +        let optional_validator_param = quote!(#field_ident); +        // same but for the ident used in a if let Some variable +        let optional_pattern_matched = if field_name.starts_with("Option<&") {            quote!(#field_ident)          } else { -          quote!(&#field_ident) +          quote!(ref #field_ident)          };          for validator in &validators { @@ -87,14 +89,14 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {                      // wrap in if-let if we have an option                      if field_name.starts_with("Option<") {                          quote!( -                            if let Some(#field_ident) = self.#field_ident { +                            if let Some(#optional_pattern_matched) = self.#field_ident {                                  if !::validator::validate_length(                                      ::validator::Validator::Length {                                          min: #min_tokens,                                          max: #max_tokens,                                          equal: #equal_tokens                                      }, -                                    #field_ident +                                    #optional_validator_param                                  ) {                                      errors.add(#name, "length");                                  } @@ -143,8 +145,8 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {                      // wrap in if-let if we have an option                      if field_name.starts_with("Option<") {                          quote!( -                            if let Some(#field_ident) = self.#field_ident { -                                if !::validator::validate_email(#field_ident) { +                            if let Some(#optional_pattern_matched) = self.#field_ident { +                                if !::validator::validate_email(#optional_validator_param) {                                      errors.add(#name, "email");                                  }                              } @@ -161,8 +163,8 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {                      // wrap in if-let if we have an option                      if field_name.starts_with("Option<") {                          quote!( -                            if let Some(#field_ident) = self.#field_ident { -                                if !::validator::validate_url(#field_ident) { +                            if let Some(#optional_pattern_matched) = self.#field_ident { +                                if !::validator::validate_url(#optional_validator_param) {                                      errors.add(#name, "url");                                  }                              } @@ -188,8 +190,8 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {                      // wrap in if-let if we have an option                      if field_name.starts_with("Option<") {                          quote!( -                            if let Some(#field_ident) = self.#field_ident { -                                match #fn_ident(#field_ident) { +                            if let Some(#optional_pattern_matched) = self.#field_ident { +                                match #fn_ident(#optional_validator_param) {                                      ::std::option::Option::Some(s) => {                                          errors.add(#name, &s);                                      }, @@ -212,7 +214,7 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {                      // wrap in if-let if we have an option                      if field_name.starts_with("Option<") {                          quote!( -                            if let Some(#field_ident) = self.#field_ident { +                            if let Some(#optional_pattern_matched) = self.#field_ident {                                  if !::validator::validate_contains(#optional_validator_param, &#n) {                                      errors.add(#name, "contains");                                  } @@ -231,8 +233,8 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {                      // wrap in if-let if we have an option                      if field_name.starts_with("Option<") {                          quote!( -                            if let Some(#field_ident) = self.#field_ident { -                                if !#re_ident.is_match(#field_ident) { +                            if let Some(#optional_pattern_matched) = self.#field_ident { +                                if !#re_ident.is_match(#optional_validator_param) {                                      errors.add(#name, "regex");                                  }                              } @@ -539,6 +541,7 @@ fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, S                                  "email" => {                                      if field_type != "String"                                          && field_type != "&str" +                                        && field_type != "Option<String>"                                          && !(field_type.starts_with("Option<") && field_type.ends_with("str>")) {                                          panic!("`email` validator can only be used on String or &str");                                      } @@ -547,6 +550,7 @@ fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, S                                  "url" => {                                      if field_type != "String"                                          && field_type != "&str" +                                        && field_type != "Option<String>"                                          && !(field_type.starts_with("Option<") && field_type.ends_with("str>")) {                                          panic!("`url` validator can only be used on String or &str");                                      } @@ -600,6 +604,8 @@ fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, S                                  if name == "length" {                                      if field_type != "String"                                          && !field_type.starts_with("Vec<") +                                        && !field_type.starts_with("Option<Vec<") +                                        && field_type != "Option<String>"                                          // a bit ugly                                          && !(field_type.starts_with("Option<") && field_type.ends_with("str>"))                                          && field_type != "&str" { diff --git a/validator_derive/tests/test_derive.rs b/validator_derive/tests/test_derive.rs index 5d61755..d456be6 100644 --- a/validator_derive/tests/test_derive.rs +++ b/validator_derive/tests/test_derive.rs @@ -274,7 +274,7 @@ fn test_can_check_regex_validator() {  #[test] -fn test_can_validate_option_fields() { +fn test_can_validate_option_fields_with_lifetime() {      lazy_static! {          static ref RE2: Regex = Regex::new(r"[a-z]{2}").unwrap();      } @@ -312,3 +312,46 @@ fn test_can_validate_option_fields() {      };      assert!(s.validate().is_ok());  } + +#[test] +fn test_can_validate_option_fields_without_lifetime() { +    lazy_static! { +        static ref RE2: Regex = Regex::new(r"[a-z]{2}").unwrap(); +    } + +    #[derive(Debug, Validate)] +    struct PutStruct { +        #[validate(length(min = "1", max = "10"))] +        name: Option<String>, +        #[validate(length(min = "1", max = "10"))] +        ids: Option<Vec<usize>>, +        #[validate(range(min = "1", max = "10"))] +        range: Option<usize>, +        #[validate(email)] +        email: Option<String>, +        #[validate(url)] +        url: Option<String>, +        #[validate(contains = "@")] +        text: Option<String>, +        #[validate(regex = "RE2")] +        re: Option<String>, +        #[validate(custom = "check_str")] +        custom: Option<String>, +    } + +    fn check_str(_: &str) -> Option<String> { +        None +    } + +    let s = PutStruct { +        name: Some("al".to_string()), +        ids: Some(vec![1, 2, 3]), +        range: Some(2), +        email: Some("hi@gmail.com".to_string()), +        url: Some("http://google.com".to_string()), +        text: Some("@someone".to_string()), +        re: Some("hi".to_string()), +        custom: Some("hey".to_string()), +    }; +    assert!(s.validate().is_ok()); +} | 
