aboutsummaryrefslogtreecommitdiffstats
path: root/validator_derive
diff options
context:
space:
mode:
authorVincent Prouillet2017-01-18 00:29:23 +0900
committerVincent Prouillet2017-01-18 00:30:44 +0900
commit32ada012eb1de7da60d979b65844d008fc75b458 (patch)
tree6fa876cff0dc3689a4421f2a5d151be2096173be /validator_derive
parentd8298ba2c96692cf4fb954393afb9fe10cb31b4c (diff)
downloadvalidator-32ada012eb1de7da60d979b65844d008fc75b458.tar.bz2
Add contains validator
Diffstat (limited to 'validator_derive')
-rw-r--r--validator_derive/Cargo.toml4
-rw-r--r--validator_derive/src/lib.rs35
-rw-r--r--validator_derive/tests/test_derive.rs33
3 files changed, 48 insertions, 24 deletions
diff --git a/validator_derive/Cargo.toml b/validator_derive/Cargo.toml
index da556a7..e5234f9 100644
--- a/validator_derive/Cargo.toml
+++ b/validator_derive/Cargo.toml
@@ -22,5 +22,5 @@ serde_json = "0.8"
compiletest_rs = "0.2"
[dependencies.validator]
-# path = "../validator"
-version = "0.2.0"
+path = "../validator"
+# version = "0.2.0"
diff --git a/validator_derive/src/lib.rs b/validator_derive/src/lib.rs
index 9725ab6..7a21ac8 100644
--- a/validator_derive/src/lib.rs
+++ b/validator_derive/src/lib.rs
@@ -75,7 +75,7 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {
},
&self.#field_ident
) {
- errors.entry(#name.to_string()).or_insert_with(|| vec![]).push("length".to_string());
+ errors.add(#name, "length");
}
)
},
@@ -85,21 +85,21 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {
::validator::Validator::Range {min: #min, max: #max},
self.#field_ident as f64
) {
- errors.entry(#name.to_string()).or_insert_with(|| vec![]).push("range".to_string());
+ errors.add(#name, "range");
}
)
},
&Validator::Email => {
quote!(
if !::validator::validate_email(&self.#field_ident) {
- errors.entry(#name.to_string()).or_insert_with(|| vec![]).push("email".to_string());
+ errors.add(#name, "email");
}
)
}
&Validator::Url => {
quote!(
if !::validator::validate_url(&self.#field_ident) {
- errors.entry(#name.to_string()).or_insert_with(|| vec![]).push("url".to_string());
+ errors.add(#name, "url");
}
)
},
@@ -107,7 +107,7 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {
let other_ident = syn::Ident::new(f.clone());
quote!(
if !::validator::validate_must_match(&self.#field_ident, &self.#other_ident) {
- errors.entry(#name.to_string()).or_insert_with(|| vec![]).push("no_match".to_string());
+ errors.add(#name, "no_match");
}
)
},
@@ -116,12 +116,19 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {
quote!(
match #fn_ident(&self.#field_ident) {
::std::option::Option::Some(s) => {
- errors.entry(#name.to_string()).or_insert_with(|| vec![]).push(s)
+ errors.add(#name, &s);
},
::std::option::Option::None => (),
};
)
},
+ &Validator::Contains(ref n) => {
+ quote!(
+ if !::validator::validate_contains(&self.#field_ident, &#n) {
+ errors.add(#name, "contains");
+ }
+ )
+ },
});
}
}
@@ -135,7 +142,7 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {
if errors.is_empty() {
match #fn_ident(self) {
::std::option::Option::Some((key, val)) => {
- errors.entry(key).or_insert_with(|| vec![]).push(val)
+ errors.add(&key, &val);
},
::std::option::Option::None => (),
}
@@ -145,7 +152,7 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {
quote!(
match #fn_ident(self) {
::std::option::Option::Some((key, val)) => {
- errors.entry(key).or_insert_with(|| vec![]).push(val)
+ errors.add(&key, &val);
},
::std::option::Option::None => (),
}
@@ -159,8 +166,7 @@ fn expand_validation(ast: &syn::MacroInput) -> quote::Tokens {
let impl_ast = quote!(
impl Validate for #ident {
fn validate(&self) -> ::std::result::Result<(), ::validator::Errors> {
- use std::collections::HashMap;
- let mut errors = HashMap::new();
+ let mut errors = ::validator::Errors::new();
#(#validations)*
@@ -416,7 +422,7 @@ fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, S
},
_ => panic!("Unexpected word validator: {}", name)
},
- // custom
+ // custom, contains, must_match
syn::MetaItem::NameValue(ref name, ref val) => {
match name.to_string().as_ref() {
"custom" => {
@@ -425,6 +431,12 @@ fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, S
None => error("invalid argument for `custom` validator: only strings are allowed"),
};
},
+ "contains" => {
+ match lit_to_string(val) {
+ Some(s) => validators.push(Validator::Contains(s)),
+ None => error("invalid argument for `contains` validator: only strings are allowed"),
+ };
+ },
"must_match" => {
match lit_to_string(val) {
Some(s) => {
@@ -555,6 +567,7 @@ fn lit_to_float(lit: &syn::Lit) -> Option<f64> {
fn lit_to_bool(lit: &syn::Lit) -> Option<bool> {
match *lit {
syn::Lit::Bool(ref s) => Some(*s),
+ // TODO: remove when attr_literals is stable
syn::Lit::Str(ref s, _) => if s == "true" { Some(true) } else { Some(false) },
_ => None,
}
diff --git a/validator_derive/tests/test_derive.rs b/validator_derive/tests/test_derive.rs
index 9b9bad7..c7e78cc 100644
--- a/validator_derive/tests/test_derive.rs
+++ b/validator_derive/tests/test_derive.rs
@@ -56,7 +56,7 @@ struct SignupData2 {
#[derive(Debug, Validate, Deserialize)]
#[validate(schema(function = "validate_signup3"))]
struct SignupData3 {
- #[validate(email)]
+ #[validate(email, contains = "bob")]
mail: String,
#[validate(range(min = "18", max = "20"))]
age: u32,
@@ -96,7 +96,7 @@ fn test_bad_email_fails_validation() {
};
let res = signup.validate();
assert!(res.is_err());
- let errs = res.unwrap_err();
+ let errs = res.unwrap_err().inner();
assert!(errs.contains_key("mail"));
assert_eq!(errs["mail"], vec!["email".to_string()]);
}
@@ -111,7 +111,7 @@ fn test_bad_url_fails_validation() {
};
let res = signup.validate();
assert!(res.is_err());
- let errs = res.unwrap_err();
+ let errs = res.unwrap_err().inner();
assert!(errs.contains_key("site"));
assert_eq!(errs["site"], vec!["url".to_string()]);
}
@@ -126,8 +126,7 @@ fn test_bad_length_fails_validation_and_points_to_original_name() {
};
let res = signup.validate();
assert!(res.is_err());
- let errs = res.unwrap_err();
- println!("{:?}", errs);
+ let errs = res.unwrap_err().inner();
assert!(errs.contains_key("firstName"));
assert_eq!(errs["firstName"], vec!["length".to_string()]);
}
@@ -143,7 +142,7 @@ fn test_bad_range_fails_validation() {
};
let res = signup.validate();
assert!(res.is_err());
- let errs = res.unwrap_err();
+ let errs = res.unwrap_err().inner();
assert!(errs.contains_key("age"));
assert_eq!(errs["age"], vec!["range".to_string()]);
}
@@ -158,7 +157,7 @@ fn test_can_have_multiple_errors() {
};
let res = signup.validate();
assert!(res.is_err());
- let errs = res.unwrap_err();
+ let errs = res.unwrap_err().inner();
assert!(errs.contains_key("age"));
assert!(errs.contains_key("firstName"));
assert_eq!(errs["age"], vec!["range".to_string()]);
@@ -175,7 +174,7 @@ fn test_custom_validation_error() {
};
let res = signup.validate();
assert!(res.is_err());
- let errs = res.unwrap_err();
+ let errs = res.unwrap_err().inner();
assert!(errs.contains_key("firstName"));
assert_eq!(errs["firstName"], vec!["terrible_username".to_string()]);
}
@@ -209,7 +208,7 @@ fn test_can_fail_struct_validation_new_key() {
};
let res = signup.validate();
assert!(res.is_err());
- let errs = res.unwrap_err();
+ let errs = res.unwrap_err().inner();
assert!(errs.contains_key("all"));
assert_eq!(errs["all"], vec!["stupid_rule".to_string()]);
}
@@ -222,7 +221,7 @@ fn test_can_fail_struct_validation_existing_key() {
};
let res = signup.validate();
assert!(res.is_err());
- let errs = res.unwrap_err();
+ let errs = res.unwrap_err().inner();
assert!(errs.contains_key("mail"));
assert_eq!(errs["mail"], vec!["email".to_string(), "stupid_rule".to_string()]);
}
@@ -235,8 +234,20 @@ fn test_skip_struct_validation_by_default_if_errors() {
};
let res = signup.validate();
assert!(res.is_err());
- let errs = res.unwrap_err();
+ let errs = res.unwrap_err().inner();
assert!(errs.contains_key("mail"));
assert_eq!(errs["mail"], vec!["email".to_string()]);
+}
+#[test]
+fn test_can_fail_contains_validation() {
+ let signup = SignupData3 {
+ mail: "bo@gmail.com".to_string(),
+ age: 18,
+ };
+ let res = signup.validate();
+ assert!(res.is_err());
+ let errs = res.unwrap_err().inner();
+ assert!(errs.contains_key("mail"));
+ assert_eq!(errs["mail"], vec!["contains".to_string()]);
}