aboutsummaryrefslogtreecommitdiffstats
path: root/validator_derive/src
diff options
context:
space:
mode:
authorVincent Prouillet2019-07-13 16:42:14 +0200
committerGitHub2019-07-13 16:42:14 +0200
commit87cf7cdac24dd0d4ea83a8a88640da95ae7ac93a (patch)
treee11ce4ab7dc807ffb1464d13f329ccec4a6a62db /validator_derive/src
parent4b9fe3939b106c151bff11e490a41212559f9a4a (diff)
parent0877c01f9a1bf5bcda3e3b235730f4d09982d8d2 (diff)
downloadvalidator-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.rs10
-rw-r--r--validator_derive/src/lib.rs4
-rw-r--r--validator_derive/src/lit.rs17
-rw-r--r--validator_derive/src/quoting.rs39
-rw-r--r--validator_derive/src/validation.rs43
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 };