From f4b11eaecb8fcc4798eb3a932a68c47ed802d96d Mon Sep 17 00:00:00 2001 From: Simon Sparks Date: Fri, 27 Jul 2018 10:02:04 +0100 Subject: Added support for validating Cow<'a, str> fields. (#56) * Added support for validating Cow<'a, str> fields. Keats/validator#55 * Corrected error message comparison in compiler-fail/length test. Keats/validator#55 --- validator_derive/Cargo.toml | 4 ++-- validator_derive/src/asserts.rs | 11 +++++++++-- validator_derive/src/lib.rs | 13 +++++++------ validator_derive/src/quoting.rs | 4 +++- validator_derive/tests/compile-fail/length/wrong_type.rs | 2 +- 5 files changed, 22 insertions(+), 12 deletions(-) (limited to 'validator_derive') diff --git a/validator_derive/Cargo.toml b/validator_derive/Cargo.toml index 3e80bbc..30c2d50 100644 --- a/validator_derive/Cargo.toml +++ b/validator_derive/Cargo.toml @@ -21,13 +21,13 @@ quote = "0.6" proc-macro2 = "0.4" if_chain = "0" validator = { version = "0.7", path = "../validator"} +regex = "1" +lazy_static = "1" [dev-dependencies] serde = "1.0" serde_derive = "1.0" serde_json = "1.0" compiletest_rs = "0.3" -regex = "1" -lazy_static = "1" diff --git a/validator_derive/src/asserts.rs b/validator_derive/src/asserts.rs index 53d76ae..cdd0028 100644 --- a/validator_derive/src/asserts.rs +++ b/validator_derive/src/asserts.rs @@ -1,3 +1,8 @@ +use regex::Regex; + +lazy_static! { + pub static ref COW_TYPE: Regex = Regex::new(r"Cow<'[a-z]+,str>").unwrap(); +} pub static NUMBER_TYPES: [&'static str; 36] = [ "usize", "u8", "u16", "u32", "u64", @@ -17,11 +22,12 @@ pub static NUMBER_TYPES: [&'static str; 36] = [ pub fn assert_string_type(name: &str, field_type: &String) { if field_type != "String" && field_type != "&str" + && !COW_TYPE.is_match(field_type) && field_type != "Option" && field_type != "Option>" && !(field_type.starts_with("Option<") && field_type.ends_with("str>")) && !(field_type.starts_with("Option>")) { - panic!("`{}` validator can only be used on String, &str or an Option of those", name); + panic!("`{}` validator can only be used on String, &str, Cow<'_,str> or an Option of those", name); } } @@ -45,9 +51,10 @@ pub fn assert_has_len(field_name: String, field_type: &String) { // a bit ugly && !(field_type.starts_with("Option<") && field_type.ends_with("str>")) && !(field_type.starts_with("Option>")) + && !COW_TYPE.is_match(field_type) && field_type != "&str" { panic!( - "Validator `length` can only be used on types `String`, `&str` or `Vec` but found `{}` for field `{}`", + "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 a0a1c82..b5a76c1 100644 --- a/validator_derive/src/lib.rs +++ b/validator_derive/src/lib.rs @@ -1,20 +1,21 @@ #![recursion_limit = "128"] #[macro_use] -extern crate quote; +extern crate if_chain; +#[macro_use] +extern crate lazy_static; extern crate proc_macro; extern crate proc_macro2; #[macro_use] -extern crate syn; +extern crate quote; +extern crate regex; #[macro_use] -extern crate if_chain; +extern crate syn; extern crate validator; -use std::collections::HashMap; - use proc_macro::TokenStream; use quote::ToTokens; - +use std::collections::HashMap; use validator::Validator; diff --git a/validator_derive/src/quoting.rs b/validator_derive/src/quoting.rs index 272226e..20ca7a7 100644 --- a/validator_derive/src/quoting.rs +++ b/validator_derive/src/quoting.rs @@ -4,7 +4,7 @@ use proc_macro2::{self, Span}; use lit::option_u64_to_tokens; use validation::{FieldValidation, SchemaValidation}; -use asserts::NUMBER_TYPES; +use asserts::{COW_TYPE, NUMBER_TYPES}; /// Pass around all the information needed for creating a validation @@ -31,6 +31,8 @@ impl FieldQuoter { if self._type.starts_with("Option<") { 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()) { quote!(self.#ident) } else { diff --git a/validator_derive/tests/compile-fail/length/wrong_type.rs b/validator_derive/tests/compile-fail/length/wrong_type.rs index a9d53d4..3dd1fb0 100644 --- a/validator_derive/tests/compile-fail/length/wrong_type.rs +++ b/validator_derive/tests/compile-fail/length/wrong_type.rs @@ -4,7 +4,7 @@ use validator::Validate; #[derive(Validate)] //~^ ERROR: proc-macro derive panicked -//~^^ HELP: Validator `length` can only be used on types `String`, `&str` or `Vec` but found `usize` +//~^^ HELP: Validator `length` can only be used on types `String`, `&str`, Cow<'_,str> or `Vec` but found `usize` struct Test { #[validate(length())] s: usize, -- cgit v1.2.3