diff options
Diffstat (limited to 'validator_derive')
| -rw-r--r-- | validator_derive/src/asserts.rs | 61 | ||||
| -rw-r--r-- | validator_derive/src/lib.rs | 148 | ||||
| -rw-r--r-- | validator_derive/src/lit.rs | 11 | ||||
| -rw-r--r-- | validator_derive/src/quoting.rs | 106 | ||||
| -rw-r--r-- | validator_derive/src/validation.rs | 117 | ||||
| -rw-r--r-- | validator_derive/tests/complex.rs | 64 | ||||
| -rw-r--r-- | validator_derive/tests/contains.rs | 16 | ||||
| -rw-r--r-- | validator_derive/tests/credit_card.rs | 16 | ||||
| -rw-r--r-- | validator_derive/tests/custom.rs | 12 | ||||
| -rw-r--r-- | validator_derive/tests/email.rs | 17 | ||||
| -rw-r--r-- | validator_derive/tests/length.rs | 16 | ||||
| -rw-r--r-- | validator_derive/tests/must_match.rs | 21 | ||||
| -rw-r--r-- | validator_derive/tests/nested.rs | 117 | ||||
| -rw-r--r-- | validator_derive/tests/phone.rs | 17 | ||||
| -rw-r--r-- | validator_derive/tests/range.rs | 16 | ||||
| -rw-r--r-- | validator_derive/tests/regex.rs | 18 | ||||
| -rw-r--r-- | validator_derive/tests/schema.rs | 22 | ||||
| -rw-r--r-- | validator_derive/tests/url.rs | 17 |
18 files changed, 402 insertions, 410 deletions
diff --git a/validator_derive/src/asserts.rs b/validator_derive/src/asserts.rs index cdd0028..1a8dfff 100644 --- a/validator_derive/src/asserts.rs +++ b/validator_derive/src/asserts.rs @@ -5,20 +5,44 @@ lazy_static! { } pub static NUMBER_TYPES: [&'static str; 36] = [ - "usize", "u8", "u16", "u32", "u64", - "isize", "i8", "i16", "i32", "i64", - "f32", "f64", - - "Option<usize>", "Option<u8>", "Option<u16>", "Option<u32>", "Option<u64>", - "Option<isize>", "Option<i8>", "Option<i16>", "Option<i32>", "Option<i64>", - "Option<f32>", "Option<f64>", - - "Option<Option<usize>>", "Option<Option<u8>>", "Option<Option<u16>>", "Option<Option<u32>>", "Option<Option<u64>>", - "Option<Option<isize>>", "Option<Option<i8>>", "Option<Option<i16>>", "Option<Option<i32>>", "Option<Option<i64>>", - "Option<Option<f32>>", "Option<Option<f64>>", + "usize", + "u8", + "u16", + "u32", + "u64", + "isize", + "i8", + "i16", + "i32", + "i64", + "f32", + "f64", + "Option<usize>", + "Option<u8>", + "Option<u16>", + "Option<u32>", + "Option<u64>", + "Option<isize>", + "Option<i8>", + "Option<i16>", + "Option<i32>", + "Option<i64>", + "Option<f32>", + "Option<f64>", + "Option<Option<usize>>", + "Option<Option<u8>>", + "Option<Option<u16>>", + "Option<Option<u32>>", + "Option<Option<u64>>", + "Option<Option<isize>>", + "Option<Option<i8>>", + "Option<Option<i16>>", + "Option<Option<i32>>", + "Option<Option<i64>>", + "Option<Option<f32>>", + "Option<Option<f64>>", ]; - pub fn assert_string_type(name: &str, field_type: &String) { if field_type != "String" && field_type != "&str" @@ -26,8 +50,12 @@ pub fn assert_string_type(name: &str, field_type: &String) { && field_type != "Option<String>" && field_type != "Option<Option<String>>" && !(field_type.starts_with("Option<") && field_type.ends_with("str>")) - && !(field_type.starts_with("Option<Option<") && field_type.ends_with("str>>")) { - panic!("`{}` validator can only be used on String, &str, Cow<'_,str> or an Option of those", name); + && !(field_type.starts_with("Option<Option<") && field_type.ends_with("str>>")) + { + panic!( + "`{}` validator can only be used on String, &str, Cow<'_,str> or an Option of those", + name + ); } } @@ -52,8 +80,9 @@ pub fn assert_has_len(field_name: String, field_type: &String) { && !(field_type.starts_with("Option<") && field_type.ends_with("str>")) && !(field_type.starts_with("Option<Option<") && field_type.ends_with("str>>")) && !COW_TYPE.is_match(field_type) - && field_type != "&str" { - panic!( + && field_type != "&str" + { + panic!( "Validator `length` can only be used on types `String`, `&str`, Cow<'_,str> or `Vec` but found `{}` for field `{}`", field_type, field_name ); diff --git a/validator_derive/src/lib.rs b/validator_derive/src/lib.rs index 2a23ba4..0647a7d 100644 --- a/validator_derive/src/lib.rs +++ b/validator_derive/src/lib.rs @@ -18,17 +18,15 @@ use quote::ToTokens; use std::collections::HashMap; use validator::Validator; - -mod lit; -mod validation; mod asserts; +mod lit; mod quoting; +mod validation; +use asserts::{assert_has_len, assert_has_range, assert_string_type, assert_type_matches}; use lit::*; +use quoting::{quote_field_validation, quote_schema_validation, FieldQuoter}; use validation::*; -use asserts::{assert_string_type, assert_type_matches, assert_has_len, assert_has_range}; -use quoting::{FieldQuoter, quote_field_validation, quote_schema_validation}; - #[proc_macro_derive(Validate, attributes(validate))] pub fn derive_validation(input: TokenStream) -> TokenStream { @@ -36,7 +34,6 @@ pub fn derive_validation(input: TokenStream) -> TokenStream { impl_validate(&ast).into() } - fn impl_validate(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { // Ensure the macro is on a struct with named fields let fields = match ast.data { @@ -45,7 +42,7 @@ fn impl_validate(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { panic!("struct has unnamed fields"); } fields.iter().cloned().collect() - }, + } _ => panic!("#[derive(Validate)] can only be used with structs"), }; @@ -61,7 +58,12 @@ fn impl_validate(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { let field_quoter = FieldQuoter::new(field_ident, name, field_type); for validation in &field_validations { - quote_field_validation(&field_quoter, validation, &mut validations, &mut nested_validations); + quote_field_validation( + &field_quoter, + validation, + &mut validations, + &mut nested_validations, + ); } } @@ -96,7 +98,6 @@ fn impl_validate(ast: &syn::DeriveInput) -> proc_macro2::TokenStream { impl_ast } - /// Find if a struct has some schema validation and returns the info if so fn find_struct_validation(struct_attrs: &Vec<syn::Attribute>) -> Option<SchemaValidation> { let error = |msg: &str| -> ! { @@ -187,7 +188,6 @@ fn find_struct_validation(struct_attrs: &Vec<syn::Attribute>) -> Option<SchemaVa None } - /// Find the types (as string) for each field of the struct /// Needed for the `must_match` filter fn find_fields_type(fields: &Vec<syn::Field>) -> HashMap<String, String> { @@ -200,8 +200,7 @@ fn find_fields_type(fields: &Vec<syn::Field>) -> HashMap<String, String> { let mut tokens = proc_macro2::TokenStream::new(); path.to_tokens(&mut tokens); tokens.to_string().replace(' ', "") - - }, + } syn::Type::Reference(syn::TypeReference { ref lifetime, ref elem, .. }) => { let mut tokens = proc_macro2::TokenStream::new(); elem.to_tokens(&mut tokens); @@ -210,8 +209,8 @@ fn find_fields_type(fields: &Vec<syn::Field>) -> HashMap<String, String> { name.insert(0, '&') } name - }, - _ => panic!("Type `{:?}` of field `{}` not supported", field.ty, field_ident) + } + _ => panic!("Type `{:?}` of field `{}` not supported", field.ty, field_ident), }; //println!("{:?}", field_type); @@ -223,12 +222,19 @@ fn find_fields_type(fields: &Vec<syn::Field>) -> HashMap<String, String> { /// Find everything we need to know about a field: its real name if it's changed from the serialization /// and the list of validators to run on it -fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, String>) -> (String, Vec<FieldValidation>) { +fn find_validators_for_field( + field: &syn::Field, + field_types: &HashMap<String, String>, +) -> (String, Vec<FieldValidation>) { let rust_ident = field.ident.clone().unwrap().to_string(); let mut field_ident = field.ident.clone().unwrap().to_string(); let error = |msg: &str| -> ! { - panic!("Invalid attribute #[validate] on field `{}`: {}", field.ident.clone().unwrap().to_string(), msg); + panic!( + "Invalid attribute #[validate] on field `{}`: {}", + field.ident.clone().unwrap().to_string(), + msg + ); }; let field_type = field_types.get(&field_ident).unwrap(); @@ -265,38 +271,40 @@ fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, S "email" => { assert_string_type("email", field_type); validators.push(FieldValidation::new(Validator::Email)); - }, + } "url" => { assert_string_type("url", field_type); validators.push(FieldValidation::new(Validator::Url)); - }, + } #[cfg(feature = "phone")] "phone" => { assert_string_type("phone", field_type); validators.push(FieldValidation::new(Validator::Phone)); - }, + } #[cfg(feature = "card")] "credit_card" => { assert_string_type("credit_card", field_type); validators.push(FieldValidation::new(Validator::CreditCard)); - }, - _ => panic!("Unexpected validator: {}", name) + } + _ => panic!("Unexpected validator: {}", name), }, // custom, contains, must_match, regex - syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) => { + syn::Meta::NameValue(syn::MetaNameValue { + ref ident, ref lit, .. + }) => { match ident.to_string().as_ref() { "custom" => { match lit_to_string(lit) { Some(s) => validators.push(FieldValidation::new(Validator::Custom(s))), None => error("invalid argument for `custom` validator: only strings are allowed"), }; - }, + } "contains" => { match lit_to_string(lit) { Some(s) => validators.push(FieldValidation::new(Validator::Contains(s))), None => error("invalid argument for `contains` validator: only strings are allowed"), }; - }, + } "regex" => { match lit_to_string(lit) { Some(s) => validators.push(FieldValidation::new(Validator::Regex(s))), @@ -311,53 +319,88 @@ fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, S }, None => error("invalid argument for `must_match` validator: only strings are allowed"), }; - }, + } v => panic!("unexpected name value validator: {:?}", v), }; - }, + } // Validators with several args syn::Meta::List(syn::MetaList { ref ident, ref nested, .. }) => { let meta_items = nested.iter().cloned().collect(); match ident.to_string().as_ref() { "length" => { assert_has_len(rust_ident.clone(), field_type); - validators.push(extract_length_validation(rust_ident.clone(), &meta_items)); - }, + validators.push(extract_length_validation( + rust_ident.clone(), + &meta_items, + )); + } "range" => { assert_has_range(rust_ident.clone(), field_type); - validators.push(extract_range_validation(rust_ident.clone(), &meta_items)); - }, + validators.push(extract_range_validation( + rust_ident.clone(), + &meta_items, + )); + } "email" | "url" | "phone" | "credit_card" => { - validators.push(extract_argless_validation(ident.to_string(), rust_ident.clone(), &meta_items)); - }, + validators.push(extract_argless_validation( + ident.to_string(), + rust_ident.clone(), + &meta_items, + )); + } "custom" => { - validators.push(extract_one_arg_validation("function", ident.to_string(), rust_ident.clone(), &meta_items)); - }, + validators.push(extract_one_arg_validation( + "function", + ident.to_string(), + rust_ident.clone(), + &meta_items, + )); + } "contains" => { - validators.push(extract_one_arg_validation("pattern", ident.to_string(), rust_ident.clone(), &meta_items)); - }, + validators.push(extract_one_arg_validation( + "pattern", + ident.to_string(), + rust_ident.clone(), + &meta_items, + )); + } "regex" => { - validators.push(extract_one_arg_validation("path", ident.to_string(), rust_ident.clone(), &meta_items)); - }, + validators.push(extract_one_arg_validation( + "path", + ident.to_string(), + rust_ident.clone(), + &meta_items, + )); + } "must_match" => { - let validation = extract_one_arg_validation("other", ident.to_string(), rust_ident.clone(), &meta_items); + let validation = extract_one_arg_validation( + "other", + ident.to_string(), + rust_ident.clone(), + &meta_items, + ); if let Validator::MustMatch(ref t2) = validation.validator { - assert_type_matches(rust_ident.clone(), field_type, field_types.get(t2)); + assert_type_matches( + rust_ident.clone(), + field_type, + field_types.get(t2), + ); } validators.push(validation); - }, - v => panic!("unexpected list validator: {:?}", v) + } + v => panic!("unexpected list validator: {:?}", v), } - }, + } }, - _ => unreachable!("Found a non Meta while looking for validators") + _ => unreachable!("Found a non Meta while looking for validators"), }; } - }, - Some(syn::Meta::Word(_)) => { - validators.push(FieldValidation::new(Validator::Nested)) - }, - _ => unreachable!("Got something other than a list of attributes while checking field `{}`", field_ident), + } + Some(syn::Meta::Word(_)) => validators.push(FieldValidation::new(Validator::Nested)), + _ => unreachable!( + "Got something other than a list of attributes while checking field `{}`", + field_ident + ), } } @@ -384,12 +427,12 @@ fn find_original_field_name(meta_items: &Vec<&syn::NestedMeta>) -> Option<String if ident == "rename" { original_name = Some(lit_to_string(lit).unwrap()); } - }, + } syn::Meta::List(syn::MetaList { ref nested, .. }) => { return find_original_field_name(&nested.iter().collect()); } }, - _ => unreachable!() + _ => unreachable!(), }; if original_name.is_some() { @@ -399,4 +442,3 @@ fn find_original_field_name(meta_items: &Vec<&syn::NestedMeta>) -> Option<String original_name } - diff --git a/validator_derive/src/lit.rs b/validator_derive/src/lit.rs index 1864d8f..14e3f56 100644 --- a/validator_derive/src/lit.rs +++ b/validator_derive/src/lit.rs @@ -1,6 +1,5 @@ -use syn; use proc_macro2; - +use syn; pub fn lit_to_string(lit: &syn::Lit) -> Option<String> { match *lit { @@ -32,7 +31,11 @@ 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) }, + syn::Lit::Str(ref s) => if s.value() == "true" { + Some(true) + } else { + Some(false) + }, _ => None, } } @@ -40,6 +43,6 @@ pub fn lit_to_bool(lit: &syn::Lit) -> Option<bool> { pub fn option_u64_to_tokens(opt: Option<u64>) -> proc_macro2::TokenStream { match opt { Some(ref t) => quote!(::std::option::Option::Some(#t)), - None => quote!(::std::option::Option::None) + None => quote!(::std::option::Option::None), } } diff --git a/validator_derive/src/quoting.rs b/validator_derive/src/quoting.rs index b47db6a..f94d8fc 100644 --- a/validator_derive/src/quoting.rs +++ b/validator_derive/src/quoting.rs @@ -1,11 +1,10 @@ -use validator::Validator; -use syn; use proc_macro2::{self, Span}; +use syn; +use validator::Validator; +use asserts::{COW_TYPE, NUMBER_TYPES}; use lit::option_u64_to_tokens; use validation::{FieldValidation, SchemaValidation}; -use asserts::{COW_TYPE, NUMBER_TYPES}; - /// Pass around all the information needed for creating a validation #[derive(Debug)] @@ -54,8 +53,10 @@ impl FieldQuoter { pub fn get_optional_validator_param(&self) -> proc_macro2::TokenStream { let ident = &self.ident; - if self._type.starts_with("Option<&") || self._type.starts_with("Option<Option<&") - || NUMBER_TYPES.contains(&self._type.as_ref()) { + if self._type.starts_with("Option<&") + || self._type.starts_with("Option<Option<&") + || NUMBER_TYPES.contains(&self._type.as_ref()) + { quote!(#ident) } else { quote!(ref #ident) @@ -72,19 +73,18 @@ impl FieldQuoter { if let Some(Some(#optional_pattern_matched)) = self.#field_ident { #tokens } - ) + ); } else if self._type.starts_with("Option<") { return quote!( if let Some(#optional_pattern_matched) = self.#field_ident { #tokens } - ) + ); } tokens } - /// Wrap the quoted output of a validation with a for loop if /// the field type is a vector pub fn wrap_if_vector(&self, tokens: proc_macro2::TokenStream) -> proc_macro2::TokenStream { @@ -99,7 +99,7 @@ impl FieldQuoter { result }).collect(); result = ::validator::ValidationErrors::merge_all(result, #field_name, results); - }) + }); } tokens @@ -121,8 +121,10 @@ fn quote_error(validation: &FieldValidation) -> proc_macro2::TokenStream { ) } - -pub fn quote_length_validation(field_quoter: &FieldQuoter, validation: &FieldValidation) -> proc_macro2::TokenStream { +pub fn quote_length_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, +) -> proc_macro2::TokenStream { let field_name = &field_quoter.name; let validator_param = field_quoter.quote_validator_param(); @@ -173,7 +175,10 @@ pub fn quote_length_validation(field_quoter: &FieldQuoter, validation: &FieldVal unreachable!() } -pub fn quote_range_validation(field_quoter: &FieldQuoter, validation: &FieldValidation) -> proc_macro2::TokenStream { +pub fn quote_range_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, +) -> proc_macro2::TokenStream { let field_name = &field_quoter.name; let quoted_ident = field_quoter.quote_validator_param(); @@ -201,7 +206,10 @@ pub fn quote_range_validation(field_quoter: &FieldQuoter, validation: &FieldVali } #[cfg(feature = "card")] -pub fn quote_credit_card_validation(field_quoter: &FieldQuoter, validation: &FieldValidation) -> proc_macro2::TokenStream { +pub fn quote_credit_card_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, +) -> proc_macro2::TokenStream { let field_name = &field_quoter.name; let validator_param = field_quoter.quote_validator_param(); @@ -218,7 +226,10 @@ pub fn quote_credit_card_validation(field_quoter: &FieldQuoter, validation: &Fie } #[cfg(feature = "phone")] -pub fn quote_phone_validation(field_quoter: &FieldQuoter, validation: &FieldValidation) -> proc_macro2::TokenStream { +pub fn quote_phone_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, +) -> proc_macro2::TokenStream { let field_name = &field_quoter.name; let validator_param = field_quoter.quote_validator_param(); @@ -234,7 +245,10 @@ pub fn quote_phone_validation(field_quoter: &FieldQuoter, validation: &FieldVali field_quoter.wrap_if_option(quoted) } -pub fn quote_url_validation(field_quoter: &FieldQuoter, validation: &FieldValidation) -> proc_macro2::TokenStream { +pub fn quote_url_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, +) -> proc_macro2::TokenStream { let field_name = &field_quoter.name; let validator_param = field_quoter.quote_validator_param(); @@ -250,7 +264,10 @@ pub fn quote_url_validation(field_quoter: &FieldQuoter, validation: &FieldValida field_quoter.wrap_if_option(quoted) } -pub fn quote_email_validation(field_quoter: &FieldQuoter, validation: &FieldValidation) -> proc_macro2::TokenStream { +pub fn quote_email_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, +) -> proc_macro2::TokenStream { let field_name = &field_quoter.name; let validator_param = field_quoter.quote_validator_param(); @@ -266,7 +283,10 @@ pub fn quote_email_validation(field_quoter: &FieldQuoter, validation: &FieldVali field_quoter.wrap_if_option(quoted) } -pub fn quote_must_match_validation(field_quoter: &FieldQuoter, validation: &FieldValidation) -> proc_macro2::TokenStream { +pub fn quote_must_match_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, +) -> proc_macro2::TokenStream { let ident = &field_quoter.ident; let field_name = &field_quoter.name; @@ -288,7 +308,10 @@ pub fn quote_must_match_validation(field_quoter: &FieldQuoter, validation: &Fiel unreachable!(); } -pub fn quote_custom_validation(field_quoter: &FieldQuoter, validation: &FieldValidation) -> proc_macro2::TokenStream { +pub fn quote_custom_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, +) -> proc_macro2::TokenStream { let field_name = &field_quoter.name; let validator_param = field_quoter.quote_validator_param(); @@ -317,7 +340,10 @@ pub fn quote_custom_validation(field_quoter: &FieldQuoter, validation: &FieldVal unreachable!(); } -pub fn quote_contains_validation(field_quoter: &FieldQuoter, validation: &FieldValidation) -> proc_macro2::TokenStream { +pub fn quote_contains_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, +) -> proc_macro2::TokenStream { let field_name = &field_quoter.name; let validator_param = field_quoter.quote_validator_param(); @@ -338,7 +364,10 @@ pub fn quote_contains_validation(field_quoter: &FieldQuoter, validation: &FieldV unreachable!(); } -pub fn quote_regex_validation(field_quoter: &FieldQuoter, validation: &FieldValidation) -> proc_macro2::TokenStream { +pub fn quote_regex_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, +) -> proc_macro2::TokenStream { let field_name = &field_quoter.name; let validator_param = field_quoter.quote_validator_param(); @@ -359,27 +388,42 @@ pub fn quote_regex_validation(field_quoter: &FieldQuoter, validation: &FieldVali unreachable!(); } -pub fn quote_nested_validation(field_quoter: &FieldQuoter) -> proc_macro2::TokenStream { +pub fn quote_nested_validation(field_quoter: &FieldQuoter) -> proc_macro2::TokenStream { let field_name = &field_quoter.name; let validator_field = field_quoter.quote_validator_field(); let quoted = quote!(result = ::validator::ValidationErrors::merge(result, #field_name, #validator_field.validate());); field_quoter.wrap_if_option(field_quoter.wrap_if_vector(quoted)) } -pub fn quote_field_validation(field_quoter: &FieldQuoter, validation: &FieldValidation, - validations: &mut Vec<proc_macro2::TokenStream>, - nested_validations: &mut Vec<proc_macro2::TokenStream>) { +pub fn quote_field_validation( + field_quoter: &FieldQuoter, + validation: &FieldValidation, + validations: &mut Vec<proc_macro2::TokenStream>, + nested_validations: &mut Vec<proc_macro2::TokenStream>, +) { match validation.validator { - Validator::Length {..} => validations.push(quote_length_validation(&field_quoter, validation)), - Validator::Range {..} => validations.push(quote_range_validation(&field_quoter, validation)), + Validator::Length { .. } => { + validations.push(quote_length_validation(&field_quoter, validation)) + } + Validator::Range { .. } => { + validations.push(quote_range_validation(&field_quoter, validation)) + } Validator::Email => validations.push(quote_email_validation(&field_quoter, validation)), Validator::Url => validations.push(quote_url_validation(&field_quoter, validation)), - Validator::MustMatch(_) => validations.push(quote_must_match_validation(&field_quoter, validation)), - Validator::Custom(_) => validations.push(quote_custom_validation(&field_quoter, validation)), - Validator::Contains(_) => validations.push(quote_contains_validation(&field_quoter, validation)), + Validator::MustMatch(_) => { + validations.push(quote_must_match_validation(&field_quoter, validation)) + } + Validator::Custom(_) => { + validations.push(quote_custom_validation(&field_quoter, validation)) + } + Validator::Contains(_) => { + validations.push(quote_contains_validation(&field_quoter, validation)) + } Validator::Regex(_) => validations.push(quote_regex_validation(&field_quoter, validation)), #[cfg(feature = "card")] - Validator::CreditCard => validations.push(quote_credit_card_validation(&field_quoter, validation)), + Validator::CreditCard => { + validations.push(quote_credit_card_validation(&field_quoter, validation)) + } #[cfg(feature = "phone")] Validator::Phone => validations.push(quote_phone_validation(&field_quoter, validation)), Validator::Nested => nested_validations.push(quote_nested_validation(&field_quoter)), diff --git a/validator_derive/src/validation.rs b/validator_derive/src/validation.rs index 227b9d9..a9762db 100644 --- a/validator_derive/src/validation.rs +++ b/validator_derive/src/validation.rs @@ -4,7 +4,6 @@ use validator::Validator; use lit::*; - #[derive(Debug)] pub struct SchemaValidation { pub function: String, @@ -13,7 +12,6 @@ pub struct SchemaValidation { pub message: Option<String>, } - #[derive(Debug)] pub struct FieldValidation { pub code: String, @@ -23,15 +21,14 @@ pub struct FieldValidation { impl FieldValidation { pub fn new(validator: Validator) -> FieldValidation { - FieldValidation { - code: validator.code().to_string(), - validator, - message: None, - } + FieldValidation { code: validator.code().to_string(), validator, message: None } } } -pub fn extract_length_validation(field: String, meta_items: &Vec<syn::NestedMeta>) -> FieldValidation { +pub fn extract_length_validation( + field: String, + meta_items: &Vec<syn::NestedMeta>, +) -> FieldValidation { let mut min = None; let mut max = None; let mut equal = None; @@ -71,7 +68,10 @@ pub fn extract_length_validation(field: String, meta_items: &Vec<syn::NestedMeta )) } } else { - panic!("unexpected item {:?} while parsing `length` validator of field {}", item, field) + panic!( + "unexpected item {:?} while parsing `length` validator of field {}", + item, field + ) } } } @@ -91,12 +91,15 @@ pub fn extract_length_validation(field: String, meta_items: &Vec<syn::NestedMeta } } -pub fn extract_range_validation(field: String, meta_items: &Vec<syn::NestedMeta>) -> FieldValidation { +pub fn extract_range_validation( + field: String, + meta_items: &Vec<syn::NestedMeta>, +) -> FieldValidation { let mut min = 0.0; let mut max = 0.0; let (message, code) = extract_message_and_code("range", &field, meta_items); - + let error = |msg: &str| -> ! { panic!("Invalid attribute #[validate] on field `{}`: {}", field, msg); }; @@ -108,32 +111,33 @@ pub fn extract_range_validation(field: String, meta_items: &Vec<syn::NestedMeta> 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) { + 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, None => error("invalid argument type for `min` of `range` validator: only integers are allowed") }; - has_min = true; - }, - "max" => { - max = match lit_to_float(lit) { + has_min = true; + } + "max" => { + max = match lit_to_float(lit) { Some(s) => s, None => error("invalid argument type for `max` of `range` validator: only integers are allowed") }; - has_max = true; - }, - v => error(&format!( - "unknown argument `{}` for validator `range` (it only has `min`, `max`)", - v - )) + has_max = true; } + v => error(&format!( + "unknown argument `{}` for validator `range` (it only has `min`, `max`)", + v + )), }, - _ => panic!("unexpected item {:?} while parsing `range` validator", item) + _ => panic!("unexpected item {:?} while parsing `range` validator", item), }, - _=> unreachable!() + _ => unreachable!(), } } @@ -150,7 +154,11 @@ pub fn extract_range_validation(field: String, meta_items: &Vec<syn::NestedMeta> } /// Extract url/email/phone field validation with a code or a message -pub fn extract_argless_validation(validator_name: String, field: String, meta_items: &Vec<syn::NestedMeta>) -> FieldValidation { +pub fn extract_argless_validation( + validator_name: String, + field: String, + meta_items: &Vec<syn::NestedMeta>, +) -> FieldValidation { let (message, code) = extract_message_and_code(&validator_name, &field, meta_items); for meta_item in meta_items { @@ -162,12 +170,12 @@ pub fn extract_argless_validation(validator_name: String, field: String, meta_it v => panic!( "Unknown argument `{}` for validator `{}` on field `{}`", v, validator_name, field - ) + ), } - }, - _ => panic!("unexpected item {:?} while parsing `range` validator", item) + } + _ => panic!("unexpected item {:?} while parsing `range` validator", item), }, - _=> unreachable!() + _ => unreachable!(), } } @@ -177,7 +185,7 @@ pub fn extract_argless_validation(validator_name: String, field: String, meta_it "credit_card" => Validator::CreditCard, #[cfg(feature = "phone")] "phone" => Validator::Phone, - _ => Validator::Url + _ => Validator::Url, }; FieldValidation { @@ -188,7 +196,12 @@ pub fn extract_argless_validation(validator_name: String, field: String, meta_it } /// For custom, contains, regex, must_match -pub fn extract_one_arg_validation(val_name: &str, validator_name: String, field: String, meta_items: &Vec<syn::NestedMeta>) -> FieldValidation { +pub fn extract_one_arg_validation( + val_name: &str, + validator_name: String, + field: String, + meta_items: &Vec<syn::NestedMeta>, +) -> FieldValidation { let mut value = None; let (message, code) = extract_message_and_code(&validator_name, &field, meta_items); @@ -206,21 +219,24 @@ pub fn extract_one_arg_validation(val_name: &str, validator_name: String, field: val_name, validator_name, field ), }; - }, + } v => panic!( "Unknown argument `{}` for validator `{}` on field `{}`", v, validator_name, field - ) + ), } - }, - _ => panic!("unexpected item {:?} while parsing `range` validator", item) + } + _ => panic!("unexpected item {:?} while parsing `range` validator", item), }, - _=> unreachable!() + _ => unreachable!(), } } if value.is_none() { - panic!("Missing argument `{}` for validator `{}` on field `{}`", val_name, validator_name, field); + panic!( + "Missing argument `{}` for validator `{}` on field `{}`", + val_name, validator_name, field + ); } let validator = match validator_name.as_ref() { @@ -238,12 +254,21 @@ pub fn extract_one_arg_validation(val_name: &str, validator_name: String, field: } } -fn extract_message_and_code(validator_name: &str, field: &str, meta_items: &Vec<syn::NestedMeta>) -> (Option<String>, Option<String>) { +fn extract_message_and_code( + validator_name: &str, + field: &str, + meta_items: &Vec<syn::NestedMeta>, +) -> (Option<String>, Option<String>) { let mut message = None; let mut code = None; for meta_item in meta_items { - if let syn::NestedMeta::Meta(syn::Meta::NameValue(syn::MetaNameValue { ref ident , ref lit, .. })) = *meta_item { + if let syn::NestedMeta::Meta(syn::Meta::NameValue(syn::MetaNameValue { + ref ident, + ref lit, + .. + })) = *meta_item + { match ident.to_string().as_ref() { "code" => { code = match lit_to_string(lit) { @@ -253,7 +278,7 @@ fn extract_message_and_code(validator_name: &str, field: &str, meta_items: &Vec< validator_name, field ), }; - }, + } "message" => { message = match lit_to_string(lit) { Some(s) => Some(s), @@ -262,8 +287,8 @@ fn extract_message_and_code(validator_name: &str, field: &str, meta_items: &Vec< validator_name, field ), }; - }, - _ => continue + } + _ => continue, } } } diff --git a/validator_derive/tests/complex.rs b/validator_derive/tests/complex.rs index 0df26c0..7826a49 100644 --- a/validator_derive/tests/complex.rs +++ b/validator_derive/tests/complex.rs @@ -3,15 +3,14 @@ extern crate validator_derive; extern crate validator; #[macro_use] extern crate serde_derive; -extern crate serde_json; extern crate regex; +extern crate serde_json; #[macro_use] extern crate lazy_static; use regex::Regex; -use validator::{Validate, ValidationError, ValidationErrors, ValidationErrorsKind}; use std::collections::HashMap; - +use validator::{Validate, ValidationError, ValidationErrors, ValidationErrorsKind}; fn validate_unique_username(username: &str) -> Result<(), ValidationError> { if username == "xXxShad0wxXx" { @@ -46,13 +45,13 @@ struct SignupData { #[validate] card: Option<Card>, #[validate] - preferences: Vec<Preference> + preferences: Vec<Preference>, } #[derive(Debug, Validate, Deserialize)] struct Phone { #[validate(phone)] - number: String + number: String, } #[derive(Debug, Validate, Deserialize)] @@ -77,19 +76,9 @@ fn is_fine_with_many_valid_validations() { site: "http://hello.com".to_string(), first_name: "Bob".to_string(), age: 18, - phone: Phone { - number: "+14152370800".to_string() - }, - card: Some(Card { - number: "5236313877109142".to_string(), - cvv: 123 - }), - preferences: vec![ - Preference { - name: "marketing".to_string(), - value: false - }, - ] + phone: Phone { number: "+14152370800".to_string() }, + card: Some(Card { number: "5236313877109142".to_string(), cvv: 123 }), + preferences: vec![Preference { name: "marketing".to_string(), value: false }], }; assert!(signup.validate().is_ok()); @@ -102,19 +91,9 @@ fn failed_validation_points_to_original_field_name() { site: "http://hello.com".to_string(), first_name: "".to_string(), age: 18, - phone: Phone { - number: "123 invalid".to_string(), - }, - card: Some(Card { - number: "1234567890123456".to_string(), - cvv: 1 - }), - preferences: vec![ - Preference { - name: "abc".to_string(), - value: true - }, - ] + phone: Phone { number: "123 invalid".to_string() }, + card: Some(Card { number: "1234567890123456".to_string(), cvv: 1 }), + preferences: vec![Preference { name: "abc".to_string(), value: true }], }; let res = signup.validate(); // println!("{}", serde_json::to_string(&res).unwrap()); @@ -286,9 +265,7 @@ fn test_works_with_question_mark_operator() { site: "http://hello.com".to_string(), first_name: "Bob".to_string(), age: 18, - phone: Phone { - number: "+14152370800".to_string() - }, + phone: Phone { number: "+14152370800".to_string() }, card: None, preferences: Vec::new(), }; @@ -314,27 +291,18 @@ fn test_works_with_none_values() { range: Option<usize>, } - let p = PutStruct { - name: None, - address: None, - age: None, - range: None, - }; + let p = PutStruct { name: None, address: None, age: None, range: None }; - let q = PutStruct { - name: None, - address: Some(None), - age: Some(None), - range: None, - }; + let q = PutStruct { name: None, address: Some(None), age: Some(None), range: None }; assert!(p.validate().is_ok()); assert!(q.validate().is_ok()); } fn unwrap_map<F>(errors: &Box<ValidationErrors>, f: F) - where F: FnOnce(HashMap<&'static str, ValidationErrorsKind>) +where + F: FnOnce(HashMap<&'static str, ValidationErrorsKind>), { let errors = *errors.clone(); f(errors.errors()); -}
\ No newline at end of file +} diff --git a/validator_derive/tests/contains.rs b/validator_derive/tests/contains.rs index 5e9060e..1fd568d 100644 --- a/validator_derive/tests/contains.rs +++ b/validator_derive/tests/contains.rs @@ -12,9 +12,7 @@ fn can_validate_contains_ok() { val: String, } - let s = TestStruct { - val: "hello".to_string(), - }; + let s = TestStruct { val: "hello".to_string() }; assert!(s.validate().is_ok()); } @@ -27,9 +25,7 @@ fn value_not_containing_needle_fails_validation() { val: String, } - let s = TestStruct { - val: String::new(), - }; + let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -47,9 +43,7 @@ fn can_specify_code_for_contains() { #[validate(contains(pattern = "he", code = "oops"))] val: String, } - let s = TestStruct { - val: String::new(), - }; + let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -65,9 +59,7 @@ fn can_specify_message_for_contains() { #[validate(contains(pattern = "he", message = "oops"))] val: String, } - let s = TestStruct { - val: String::new(), - }; + let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); diff --git a/validator_derive/tests/credit_card.rs b/validator_derive/tests/credit_card.rs index b1a9da3..d212c48 100644 --- a/validator_derive/tests/credit_card.rs +++ b/validator_derive/tests/credit_card.rs @@ -13,9 +13,7 @@ fn can_validate_valid_card_number() { val: String, } - let s = TestStruct { - val: "5236313877109142".to_string(), - }; + let s = TestStruct { val: "5236313877109142".to_string() }; assert!(s.validate().is_ok()); } @@ -29,9 +27,7 @@ fn bad_credit_card_fails_validation() { val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -49,9 +45,7 @@ fn can_specify_code_for_credit_card() { #[validate(credit_card(code = "oops"))] val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -68,9 +62,7 @@ fn can_specify_message_for_credit_card() { #[validate(credit_card(message = "oops"))] val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); diff --git a/validator_derive/tests/custom.rs b/validator_derive/tests/custom.rs index cd1b354..c13853d 100644 --- a/validator_derive/tests/custom.rs +++ b/validator_derive/tests/custom.rs @@ -20,9 +20,7 @@ fn can_validate_custom_fn_ok() { val: String, } - let s = TestStruct { - val: "hello".to_string(), - }; + let s = TestStruct { val: "hello".to_string() }; assert!(s.validate().is_ok()); } @@ -35,9 +33,7 @@ fn can_fail_custom_fn_validation() { val: String, } - let s = TestStruct { - val: String::new(), - }; + let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -54,9 +50,7 @@ fn can_specify_message_for_custom_fn() { #[validate(custom(function = "invalid_custom_fn", message = "oops"))] val: String, } - let s = TestStruct { - val: String::new(), - }; + let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); diff --git a/validator_derive/tests/email.rs b/validator_derive/tests/email.rs index 4fbc123..665f0da 100644 --- a/validator_derive/tests/email.rs +++ b/validator_derive/tests/email.rs @@ -4,7 +4,6 @@ extern crate validator; use validator::Validate; - #[test] fn can_validate_valid_email() { #[derive(Debug, Validate)] @@ -13,9 +12,7 @@ fn can_validate_valid_email() { val: String, } - let s = TestStruct { - val: "bob@bob.com".to_string(), - }; + let s = TestStruct { val: "bob@bob.com".to_string() }; assert!(s.validate().is_ok()); } @@ -28,9 +25,7 @@ fn bad_email_fails_validation() { val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -47,9 +42,7 @@ fn can_specify_code_for_email() { #[validate(email(code = "oops"))] val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -65,9 +58,7 @@ fn can_specify_message_for_email() { #[validate(email(message = "oops"))] val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); diff --git a/validator_derive/tests/length.rs b/validator_derive/tests/length.rs index 12bffc6..6ad6272 100644 --- a/validator_derive/tests/length.rs +++ b/validator_derive/tests/length.rs @@ -12,9 +12,7 @@ fn can_validate_length_ok() { val: String, } - let s = TestStruct { - val: "hello".to_string(), - }; + let s = TestStruct { val: "hello".to_string() }; assert!(s.validate().is_ok()); } @@ -27,9 +25,7 @@ fn value_out_of_length_fails_validation() { val: String, } - let s = TestStruct { - val: String::new(), - }; + let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -48,9 +44,7 @@ fn can_specify_code_for_length() { #[validate(length(min = "5", max = "10", code = "oops"))] val: String, } - let s = TestStruct { - val: String::new(), - }; + let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -66,9 +60,7 @@ fn can_specify_message_for_length() { #[validate(length(min = "5", max = "10", message = "oops"))] val: String, } - let s = TestStruct { - val: String::new(), - }; + let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); diff --git a/validator_derive/tests/must_match.rs b/validator_derive/tests/must_match.rs index a8c95f9..32b3016 100644 --- a/validator_derive/tests/must_match.rs +++ b/validator_derive/tests/must_match.rs @@ -4,7 +4,6 @@ extern crate validator; use validator::Validate; - #[test] fn can_validate_valid_must_match() { #[derive(Debug, Validate)] @@ -14,10 +13,7 @@ fn can_validate_valid_must_match() { val2: String, } - let s = TestStruct { - val: "bob".to_string(), - val2: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string(), val2: "bob".to_string() }; assert!(s.validate().is_ok()); } @@ -31,10 +27,7 @@ fn not_matching_fails_validation() { val2: String, } - let s = TestStruct { - val: "bob".to_string(), - val2: "bobby".to_string(), - }; + let s = TestStruct { val: "bob".to_string(), val2: "bobby".to_string() }; let res = s.validate(); assert!(res.is_err()); @@ -54,10 +47,7 @@ fn can_specify_code_for_must_match() { val: String, val2: String, } - let s = TestStruct { - val: "bob".to_string(), - val2: "bobb".to_string(), - }; + 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(); @@ -74,10 +64,7 @@ fn can_specify_message_for_must_match() { val: String, val2: String, } - let s = TestStruct { - val: "bob".to_string(), - val2: "bobb".to_string(), - }; + 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(); diff --git a/validator_derive/tests/nested.rs b/validator_derive/tests/nested.rs index 4f03714..a95b0ef 100644 --- a/validator_derive/tests/nested.rs +++ b/validator_derive/tests/nested.rs @@ -4,8 +4,10 @@ extern crate validator; #[macro_use] extern crate serde_derive; -use validator::{validate_length, Validate, ValidationError, ValidationErrors, ValidationErrorsKind, Validator}; use std::{borrow::Cow, collections::HashMap}; +use validator::{ + validate_length, Validate, ValidationError, ValidationErrors, ValidationErrorsKind, Validator, +}; #[derive(Debug, Validate)] struct Root<'a> { @@ -54,12 +56,7 @@ struct Child { fn is_fine_with_nested_validations() { let root = Root { value: "valid".to_string(), - a: &A { - value: "valid".to_string(), - b: B { - value: "valid".to_string(), - } - } + a: &A { value: "valid".to_string(), b: B { value: "valid".to_string() } }, }; assert!(root.validate().is_ok()); @@ -69,12 +66,7 @@ fn is_fine_with_nested_validations() { fn failed_validation_points_to_original_field_names() { let root = Root { value: String::new(), - a: &A { - value: String::new(), - b: B { - value: String::new(), - } - } + a: &A { value: String::new(), b: B { value: String::new() } }, }; let res = root.validate(); @@ -122,11 +114,7 @@ fn failed_validation_points_to_original_field_names() { #[test] fn test_can_validate_option_fields_without_lifetime() { - let instance = ParentWithOptionalChild { - child: Some(Child { - value: String::new(), - }) - }; + let instance = ParentWithOptionalChild { child: Some(Child { value: String::new() }) }; let res = instance.validate(); assert!(res.is_err()); @@ -157,13 +145,9 @@ fn test_can_validate_option_fields_with_lifetime() { child: Option<&'a Child>, } - let child = Child { - value: String::new(), - }; + let child = Child { value: String::new() }; - let instance = ParentWithLifetimeAndOptionalChild { - child: Some(&child) - }; + let instance = ParentWithLifetimeAndOptionalChild { child: Some(&child) }; let res = instance.validate(); assert!(res.is_err()); @@ -188,9 +172,7 @@ fn test_can_validate_option_fields_with_lifetime() { #[test] fn test_works_with_none_values() { - let instance = ParentWithOptionalChild { - child: None, - }; + let instance = ParentWithOptionalChild { child: None }; let res = instance.validate(); assert!(res.is_ok()); @@ -200,18 +182,10 @@ fn test_works_with_none_values() { fn test_can_validate_vector_fields() { let instance = ParentWithVectorOfChildren { child: vec![ - Child { - value: "valid".to_string(), - }, - Child { - value: String::new(), - }, - Child { - value: "valid".to_string(), - }, - Child { - value: String::new(), - } + Child { value: "valid".to_string() }, + Child { value: String::new() }, + Child { value: "valid".to_string() }, + Child { value: String::new() }, ], }; @@ -250,9 +224,7 @@ fn test_can_validate_vector_fields() { #[test] fn test_field_validations_take_priority_over_nested_validations() { - let instance = ParentWithVectorOfChildren { - child: Vec::new(), - }; + let instance = ParentWithVectorOfChildren { child: Vec::new() }; let res = instance.validate(); assert!(res.is_err()); @@ -271,7 +243,6 @@ fn test_field_validations_take_priority_over_nested_validations() { #[should_panic(expected = "Attempt to replace non-empty ValidationErrors entry")] #[allow(unused)] fn test_field_validation_errors_replaced_with_nested_validations_fails() { - #[derive(Debug)] struct ParentWithOverridingStructValidations { child: Vec<Child>, @@ -284,7 +255,10 @@ fn test_field_validation_errors_replaced_with_nested_validations_fails() { fn validate(&self) -> Result<(), ValidationErrors> { // First validate the length of the vector: let mut errors = ValidationErrors::new(); - if !validate_length(Validator::Length { min: Some(2u64), max: None, equal: None }, &self.child) { + if !validate_length( + Validator::Length { min: Some(2u64), max: None, equal: None }, + &self.child, + ) { let mut err = ValidationError::new("length"); err.add_param(Cow::from("min"), &2u64); err.add_param(Cow::from("value"), &&self.child); @@ -294,28 +268,29 @@ fn test_field_validation_errors_replaced_with_nested_validations_fails() { // Then validate the nested vector of structs without checking for existing field errors: let mut result = if errors.is_empty() { Ok(()) } else { Err(errors) }; { - let results: Vec<_> = self.child.iter().map(|child| { - let mut result = Ok(()); - result = ValidationErrors::merge(result, "child", child.validate()); - result - }).collect(); + let results: Vec<_> = self + .child + .iter() + .map(|child| { + let mut result = Ok(()); + result = ValidationErrors::merge(result, "child", child.validate()); + result + }).collect(); result = ValidationErrors::merge_all(result, "child", results); } result } } - let instance = ParentWithOverridingStructValidations { - child: vec![ - Child { - value: String::new() - }] - }; + let instance = + ParentWithOverridingStructValidations { child: vec![Child { value: String::new() }] }; instance.validate(); } #[test] -#[should_panic(expected = "Attempt to add field validation to a non-Field ValidationErrorsKind instance")] +#[should_panic( + expected = "Attempt to add field validation to a non-Field ValidationErrorsKind instance" +)] #[allow(unused)] fn test_field_validations_evaluated_after_nested_validations_fails() { #[derive(Debug)] @@ -331,16 +306,22 @@ fn test_field_validations_evaluated_after_nested_validations_fails() { // First validate the nested vector of structs: let mut result = Ok(()); if !ValidationErrors::has_error(&result, "child") { - let results: Vec<_> = self.child.iter().map(|child| { - let mut result = Ok(()); - result = ValidationErrors::merge(result, "child", child.validate()); - result - }).collect(); + let results: Vec<_> = self + .child + .iter() + .map(|child| { + let mut result = Ok(()); + result = ValidationErrors::merge(result, "child", child.validate()); + result + }).collect(); result = ValidationErrors::merge_all(result, "child", results); } // Then validate the length of the vector itself: - if !validate_length(Validator::Length { min: Some(2u64), max: None, equal: None }, &self.child) { + if !validate_length( + Validator::Length { min: Some(2u64), max: None, equal: None }, + &self.child, + ) { let mut err = ValidationError::new("length"); err.add_param(Cow::from("min"), &2u64); err.add_param(Cow::from("value"), &&self.child); @@ -353,18 +334,14 @@ fn test_field_validations_evaluated_after_nested_validations_fails() { } } - let instance = ParentWithStructValidationsFirst { - child: vec![ - Child { - value: String::new() - }] - }; + let instance = ParentWithStructValidationsFirst { child: vec![Child { value: String::new() }] }; let res = instance.validate(); } fn unwrap_map<F>(errors: &Box<ValidationErrors>, f: F) - where F: FnOnce(HashMap<&'static str, ValidationErrorsKind>) +where + F: FnOnce(HashMap<&'static str, ValidationErrorsKind>), { let errors = *errors.clone(); f(errors.errors()); -}
\ No newline at end of file +} diff --git a/validator_derive/tests/phone.rs b/validator_derive/tests/phone.rs index 3131bad..a87d037 100644 --- a/validator_derive/tests/phone.rs +++ b/validator_derive/tests/phone.rs @@ -4,7 +4,6 @@ extern crate validator; use validator::Validate; - #[cfg(feature = "phone")] #[test] fn can_validate_phone_ok() { @@ -14,9 +13,7 @@ fn can_validate_phone_ok() { val: String, } - let s = TestStruct { - val: "+14152370800".to_string(), - }; + let s = TestStruct { val: "+14152370800".to_string() }; assert!(s.validate().is_ok()); } @@ -30,9 +27,7 @@ fn bad_phone_fails_validation() { val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -49,9 +44,7 @@ fn can_specify_code_for_phone() { #[validate(phone(code = "oops"))] val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -69,9 +62,7 @@ fn can_specify_message_for_phone() { #[validate(phone(message = "oops"))] val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); diff --git a/validator_derive/tests/range.rs b/validator_derive/tests/range.rs index 084e530..4f38f18 100644 --- a/validator_derive/tests/range.rs +++ b/validator_derive/tests/range.rs @@ -12,9 +12,7 @@ fn can_validate_range_ok() { val: usize, } - let s = TestStruct { - val: 6, - }; + let s = TestStruct { val: 6 }; assert!(s.validate().is_ok()); } @@ -27,9 +25,7 @@ fn value_out_of_range_fails_validation() { val: usize, } - let s = TestStruct { - val: 11, - }; + let s = TestStruct { val: 11 }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -45,9 +41,7 @@ fn can_specify_code_for_range() { #[validate(range(min = "5", max = "10", code = "oops"))] val: usize, } - let s = TestStruct { - val: 11, - }; + let s = TestStruct { val: 11 }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -66,9 +60,7 @@ fn can_specify_message_for_range() { #[validate(range(min = "5", max = "10", message = "oops"))] val: usize, } - let s = TestStruct { - val: 1, - }; + let s = TestStruct { val: 1 }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); diff --git a/validator_derive/tests/regex.rs b/validator_derive/tests/regex.rs index b54df03..a6b9e68 100644 --- a/validator_derive/tests/regex.rs +++ b/validator_derive/tests/regex.rs @@ -5,8 +5,8 @@ extern crate lazy_static; extern crate validator_derive; extern crate validator; -use validator::Validate; use regex::Regex; +use validator::Validate; lazy_static! { static ref RE2: Regex = Regex::new(r"^[a-z]{2}$").unwrap(); @@ -20,9 +20,7 @@ fn can_validate_valid_regex() { val: String, } - let s = TestStruct { - val: "aa".to_string(), - }; + let s = TestStruct { val: "aa".to_string() }; assert!(s.validate().is_ok()); } @@ -35,9 +33,7 @@ fn bad_value_for_regex_fails_validation() { val: String, } - let s = TestStruct { - val: "2".to_string(), - }; + let s = TestStruct { val: "2".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -54,9 +50,7 @@ fn can_specify_code_for_regex() { #[validate(regex(path = "RE2", code = "oops"))] val: String, } - let s = TestStruct { - val: "2".to_string(), - }; + let s = TestStruct { val: "2".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -72,9 +66,7 @@ fn can_specify_message_for_regex() { #[validate(regex(path = "RE2", message = "oops"))] val: String, } - let s = TestStruct { - val: "2".to_string(), - }; + let s = TestStruct { val: "2".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); diff --git a/validator_derive/tests/schema.rs b/validator_derive/tests/schema.rs index 32684fa..b45f3a1 100644 --- a/validator_derive/tests/schema.rs +++ b/validator_derive/tests/schema.rs @@ -4,12 +4,11 @@ extern crate validator; use validator::{Validate, ValidationError}; - #[test] fn can_validate_schema_fn_ok() { fn valid_schema_fn(_: &TestStruct) -> Result<(), ValidationError> { - Ok(()) -} + Ok(()) + } #[derive(Debug, Validate)] #[validate(schema(function = "valid_schema_fn"))] @@ -17,9 +16,7 @@ fn can_validate_schema_fn_ok() { val: String, } - let s = TestStruct { - val: "hello".to_string(), - }; + let s = TestStruct { val: "hello".to_string() }; assert!(s.validate().is_ok()); } @@ -36,9 +33,7 @@ fn can_fail_schema_fn_validation() { val: String, } - let s = TestStruct { - val: String::new(), - }; + let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -58,9 +53,7 @@ fn can_specify_message_for_schema_fn() { struct TestStruct { val: String, } - let s = TestStruct { - val: String::new(), - }; + let s = TestStruct { val: String::new() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -82,10 +75,7 @@ fn can_choose_to_run_schema_validation_even_after_field_errors() { num: usize, } - let s = TestStruct { - val: "hello".to_string(), - num: 0, - }; + let s = TestStruct { val: "hello".to_string(), num: 0 }; let res = s.validate(); assert!(res.is_err()); diff --git a/validator_derive/tests/url.rs b/validator_derive/tests/url.rs index 5a3b791..0ac3cb1 100644 --- a/validator_derive/tests/url.rs +++ b/validator_derive/tests/url.rs @@ -4,7 +4,6 @@ extern crate validator; use validator::Validate; - #[test] fn can_validate_url_ok() { #[derive(Debug, Validate)] @@ -13,9 +12,7 @@ fn can_validate_url_ok() { val: String, } - let s = TestStruct { - val: "https://google.com".to_string(), - }; + let s = TestStruct { val: "https://google.com".to_string() }; assert!(s.validate().is_ok()); } @@ -28,9 +25,7 @@ fn bad_url_fails_validation() { val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -46,9 +41,7 @@ fn can_specify_code_for_url() { #[validate(url(code = "oops"))] val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); @@ -65,9 +58,7 @@ fn can_specify_message_for_url() { #[validate(url(message = "oops"))] val: String, } - let s = TestStruct { - val: "bob".to_string(), - }; + let s = TestStruct { val: "bob".to_string() }; let res = s.validate(); assert!(res.is_err()); let errs = res.unwrap_err().field_errors(); |
