diff options
| author | Vincent Prouillet | 2019-07-13 16:42:14 +0200 |
|---|---|---|
| committer | GitHub | 2019-07-13 16:42:14 +0200 |
| commit | 87cf7cdac24dd0d4ea83a8a88640da95ae7ac93a (patch) | |
| tree | e11ce4ab7dc807ffb1464d13f329ccec4a6a62db /validator_derive/src | |
| parent | 4b9fe3939b106c151bff11e490a41212559f9a4a (diff) | |
| parent | 0877c01f9a1bf5bcda3e3b235730f4d09982d8d2 (diff) | |
| download | validator-87cf7cdac24dd0d4ea83a8a88640da95ae7ac93a.tar.bz2 | |
Merge pull request #72 from Keats/next
Next version
Diffstat (limited to 'validator_derive/src')
| -rw-r--r-- | validator_derive/src/asserts.rs | 10 | ||||
| -rw-r--r-- | validator_derive/src/lib.rs | 4 | ||||
| -rw-r--r-- | validator_derive/src/lit.rs | 17 | ||||
| -rw-r--r-- | validator_derive/src/quoting.rs | 39 | ||||
| -rw-r--r-- | validator_derive/src/validation.rs | 43 |
5 files changed, 58 insertions, 55 deletions
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 }; |
