diff options
| author | Vincent Prouillet | 2019-10-14 20:38:48 +0200 |
|---|---|---|
| committer | Vincent Prouillet | 2019-10-14 20:51:24 +0200 |
| commit | 8fd0d392558422d95119a2e09f261bd4ac54e6d2 (patch) | |
| tree | dd525d32c62c0ff29c8d59ce2bf92a8fc4e329fc /validator_derive/src | |
| parent | 5c509da6e41726e5a80d52c10f70e582b28d145f (diff) | |
| download | validator-8fd0d392558422d95119a2e09f261bd4ac54e6d2.tar.bz2 | |
Update deps
Diffstat (limited to 'validator_derive/src')
| -rw-r--r-- | validator_derive/src/asserts.rs | 2 | ||||
| -rw-r--r-- | validator_derive/src/lib.rs | 56 | ||||
| -rw-r--r-- | validator_derive/src/lit.rs | 7 | ||||
| -rw-r--r-- | validator_derive/src/quoting.rs | 7 | ||||
| -rw-r--r-- | validator_derive/src/validation.rs | 131 |
5 files changed, 105 insertions, 98 deletions
diff --git a/validator_derive/src/asserts.rs b/validator_derive/src/asserts.rs index a5892a8..023dd0d 100644 --- a/validator_derive/src/asserts.rs +++ b/validator_derive/src/asserts.rs @@ -1,5 +1,7 @@ use regex::Regex; +use lazy_static::lazy_static; + lazy_static! { pub static ref COW_TYPE: Regex = Regex::new(r"Cow<'[a-z]+,str>").unwrap(); } diff --git a/validator_derive/src/lib.rs b/validator_derive/src/lib.rs index d8bbb3e..18472a9 100644 --- a/validator_derive/src/lib.rs +++ b/validator_derive/src/lib.rs @@ -1,19 +1,9 @@ #![recursion_limit = "128"] - -#[macro_use] -extern crate if_chain; -#[macro_use] -extern crate lazy_static; extern crate proc_macro; -extern crate proc_macro2; -#[macro_use] -extern crate quote; -extern crate regex; -#[macro_use] -extern crate syn; -extern crate validator; - -use proc_macro::TokenStream; + +use if_chain::if_chain; +use quote::quote; +use syn::parse_quote; use quote::ToTokens; use std::collections::HashMap; use validator::Validator; @@ -29,7 +19,7 @@ use quoting::{quote_field_validation, quote_schema_validation, FieldQuoter}; use validation::*; #[proc_macro_derive(Validate, attributes(validate))] -pub fn derive_validation(input: TokenStream) -> TokenStream { +pub fn derive_validation(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let ast = syn::parse(input).unwrap(); impl_validate(&ast).into() } @@ -110,11 +100,12 @@ fn find_struct_validation(struct_attrs: &Vec<syn::Attribute>) -> Option<SchemaVa } if_chain! { - if let Some(syn::Meta::List(syn::MetaList { ref nested, .. })) = attr.interpret_meta(); + if let Ok(syn::Meta::List(syn::MetaList { ref nested, .. })) = attr.parse_meta(); if let syn::NestedMeta::Meta(ref item) = nested[0]; - if let &syn::Meta::List(syn::MetaList { ref ident, ref nested, .. }) = item; + if let &syn::Meta::List(syn::MetaList { ref path, ref nested, .. }) = item; then { + let ident = path.get_ident().unwrap(); if ident != "schema" { error("Only `schema` is allowed as validator on a struct") } @@ -127,9 +118,10 @@ fn find_struct_validation(struct_attrs: &Vec<syn::Attribute>) -> Option<SchemaVa for arg in nested { if_chain! { if let syn::NestedMeta::Meta(ref item) = *arg; - if let syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) = *item; + if let syn::Meta::NameValue(syn::MetaNameValue { ref path, ref lit, .. }) = *item; then { + let ident = path.get_ident().unwrap(); match ident.to_string().as_ref() { "function" => { function = match lit_to_string(lit) { @@ -251,8 +243,8 @@ fn find_validators_for_field( has_validate = true; } - match attr.interpret_meta() { - Some(syn::Meta::List(syn::MetaList { ref nested, .. })) => { + match attr.parse_meta() { + Ok(syn::Meta::List(syn::MetaList { ref nested, .. })) => { let meta_items = nested.iter().collect(); // original name before serde rename if attr.path == parse_quote!(serde) { @@ -267,7 +259,7 @@ fn find_validators_for_field( match *meta_item { syn::NestedMeta::Meta(ref item) => match *item { // email, url, phone, credit_card, non_control_character - syn::Meta::Word(ref name) => match name.to_string().as_ref() { + syn::Meta::Path(ref name) => match name.get_ident().unwrap().to_string().as_ref() { "email" => { assert_string_type("email", field_type); validators.push(FieldValidation::new(Validator::Email)); @@ -291,12 +283,13 @@ fn find_validators_for_field( assert_string_type("non_control_character", field_type); validators.push(FieldValidation::new(Validator::NonControlCharacter)); } - _ => panic!("Unexpected validator: {}", name), + _ => panic!("Unexpected validator: {:?}", name.get_ident()), }, // custom, contains, must_match, regex syn::Meta::NameValue(syn::MetaNameValue { - ref ident, ref lit, .. + ref path, ref lit, .. }) => { + let ident = path.get_ident().unwrap(); match ident.to_string().as_ref() { "custom" => { match lit_to_string(lit) { @@ -329,8 +322,9 @@ fn find_validators_for_field( }; } // Validators with several args - syn::Meta::List(syn::MetaList { ref ident, ref nested, .. }) => { + syn::Meta::List(syn::MetaList { ref path, ref nested, .. }) => { let meta_items = nested.iter().cloned().collect(); + let ident = path.get_ident().unwrap(); match ident.to_string().as_ref() { "length" => { assert_has_len(rust_ident.clone(), field_type); @@ -401,10 +395,11 @@ fn find_validators_for_field( }; } } - Some(syn::Meta::Word(_)) => validators.push(FieldValidation::new(Validator::Nested)), - _ => unreachable!( - "Got something other than a list of attributes while checking field `{}`", - field_ident + Ok(syn::Meta::Path(_)) => validators.push(FieldValidation::new(Validator::Nested)), + Ok(syn::Meta::NameValue(_)) => panic!("Unexpected name=value argument"), + Err(e) => unreachable!( + "Got something other than a list of attributes while checking field `{}`: {:?}", + field_ident, e ), } } @@ -427,8 +422,9 @@ fn find_original_field_name(meta_items: &Vec<&syn::NestedMeta>) -> Option<String for meta_item in meta_items { match **meta_item { syn::NestedMeta::Meta(ref item) => match *item { - syn::Meta::Word(_) => continue, - syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) => { + syn::Meta::Path(_) => continue, + syn::Meta::NameValue(syn::MetaNameValue { ref path, ref lit, .. }) => { + let ident = path.get_ident().unwrap(); if ident == "rename" { original_name = Some(lit_to_string(lit).unwrap()); } diff --git a/validator_derive/src/lit.rs b/validator_derive/src/lit.rs index 41deffc..f5a9386 100644 --- a/validator_derive/src/lit.rs +++ b/validator_derive/src/lit.rs @@ -1,5 +1,6 @@ use proc_macro2; use syn; +use quote::quote; pub fn lit_to_string(lit: &syn::Lit) -> Option<String> { match *lit { @@ -10,15 +11,15 @@ 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()), + syn::Lit::Int(ref s) => Some(s.base10_parse().unwrap()), _ => None, } } 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), + syn::Lit::Float(ref s) => Some(s.base10_parse::<f64>().unwrap()), + syn::Lit::Int(ref s) => Some(s.base10_parse::<f64>().unwrap()), _ => None, } } diff --git a/validator_derive/src/quoting.rs b/validator_derive/src/quoting.rs index 6bfef0c..0ba6af2 100644 --- a/validator_derive/src/quoting.rs +++ b/validator_derive/src/quoting.rs @@ -1,10 +1,11 @@ use proc_macro2::{self, Span}; use syn; use validator::Validator; +use quote::quote; -use asserts::{COW_TYPE, NUMBER_TYPES}; -use lit::{option_f64_to_tokens, option_u64_to_tokens}; -use validation::{FieldValidation, SchemaValidation}; +use crate::asserts::{COW_TYPE, NUMBER_TYPES}; +use crate::lit::{option_f64_to_tokens, option_u64_to_tokens}; +use crate::validation::{FieldValidation, SchemaValidation}; /// Pass around all the information needed for creating a validation #[derive(Debug)] diff --git a/validator_derive/src/validation.rs b/validator_derive/src/validation.rs index be8afee..37a2d5a 100644 --- a/validator_derive/src/validation.rs +++ b/validator_derive/src/validation.rs @@ -2,7 +2,7 @@ use syn; use validator::Validator; -use lit::*; +use crate::lit::*; #[derive(Debug)] pub struct SchemaValidation { @@ -41,32 +41,33 @@ pub fn extract_length_validation( for meta_item in meta_items { if let syn::NestedMeta::Meta(ref item) = *meta_item { - if let syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) = *item { - match ident.to_string().as_ref() { - "message" | "code" => continue, - "min" => { - min = match lit_to_int(lit) { - Some(s) => Some(s), - None => error("invalid argument type for `min` of `length` validator: only integers are allowed"), - }; - }, - "max" => { - max = match lit_to_int(lit) { - Some(s) => Some(s), - None => error("invalid argument type for `max` of `length` validator: only integers are allowed"), - }; - }, - "equal" => { - equal = match lit_to_int(lit) { - Some(s) => Some(s), - None => error("invalid argument type for `equal` of `length` validator: only integers are allowed"), - }; - }, - v => error(&format!( - "unknown argument `{}` for validator `length` (it only has `min`, `max`, `equal`)", - v - )) - } + if let syn::Meta::NameValue(syn::MetaNameValue { ref path, ref lit, .. }) = *item { + let ident = path.get_ident().unwrap(); + match ident.to_string().as_ref() { + "message" | "code" => continue, + "min" => { + min = match lit_to_int(lit) { + Some(s) => Some(s), + None => error("invalid argument type for `min` of `length` validator: only integers are allowed"), + }; + }, + "max" => { + max = match lit_to_int(lit) { + Some(s) => Some(s), + None => error("invalid argument type for `max` of `length` validator: only integers are allowed"), + }; + }, + "equal" => { + equal = match lit_to_int(lit) { + Some(s) => Some(s), + None => error("invalid argument type for `equal` of `length` validator: only integers are allowed"), + }; + }, + v => error(&format!( + "unknown argument `{}` for validator `length` (it only has `min`, `max`, `equal`)", + v + )) + } } else { panic!( "unexpected item {:?} while parsing `length` validator of field {}", @@ -107,7 +108,8 @@ pub fn extract_range_validation( 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, .. }) => { + syn::Meta::NameValue(syn::MetaNameValue { ref path, ref lit, .. }) => { + let ident = path.get_ident().unwrap(); match ident.to_string().as_ref() { "message" | "code" => continue, "min" => { @@ -123,9 +125,9 @@ pub fn extract_range_validation( }; } v => error(&format!( - "unknown argument `{}` for validator `range` (it only has `min`, `max`)", - v - )), + "unknown argument `{}` for validator `range` (it only has `min`, `max`)", + v + )), } } _ => panic!("unexpected item {:?} while parsing `range` validator", item), @@ -157,15 +159,16 @@ pub fn extract_argless_validation( for meta_item in meta_items { match *meta_item { syn::NestedMeta::Meta(ref item) => match *item { - syn::Meta::NameValue(syn::MetaNameValue { ref ident, .. }) => { - match ident.to_string().as_ref() { - "message" | "code" => continue, - v => panic!( - "Unknown argument `{}` for validator `{}` on field `{}`", - v, validator_name, field - ), + syn::Meta::NameValue(syn::MetaNameValue { ref path, .. }) => { + let ident = path.get_ident().unwrap(); + match ident.to_string().as_ref() { + "message" | "code" => continue, + v => panic!( + "Unknown argument `{}` for validator `{}` on field `{}`", + v, validator_name, field + ), + } } - } _ => panic!("unexpected item {:?} while parsing `range` validator", item), }, _ => unreachable!(), @@ -203,7 +206,9 @@ pub fn extract_one_arg_validation( 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, .. }) => { + syn::Meta::NameValue(syn::MetaNameValue { ref path, ref lit, .. }) => { + + let ident = path.get_ident().unwrap(); match ident.to_string().as_ref() { "message" | "code" => continue, v if v == val_name => { @@ -259,32 +264,34 @@ fn extract_message_and_code( for meta_item in meta_items { if let syn::NestedMeta::Meta(syn::Meta::NameValue(syn::MetaNameValue { - ref ident, + ref path, ref lit, .. })) = *meta_item { - match ident.to_string().as_ref() { - "code" => { - code = match lit_to_string(lit) { - Some(s) => Some(s), - None => panic!( - "Invalid argument type for `code` for validator `{}` on field `{}`: only a string is allowed", - validator_name, field - ), - }; - } - "message" => { - message = match lit_to_string(lit) { - Some(s) => Some(s), - None => panic!( - "Invalid argument type for `message` for validator `{}` on field `{}`: only a string is allowed", - validator_name, field - ), - }; - } - _ => continue, - } + let ident = path.get_ident().unwrap(); + match ident.to_string().as_ref() { + "code" => { + code = match lit_to_string(lit) { + Some(s) => Some(s), + None => panic!( + "Invalid argument type for `code` for validator `{}` on field `{}`: only a string is allowed", + validator_name, field + ), + }; + } + "message" => { + message = match lit_to_string(lit) { + Some(s) => Some(s), + None => panic!( + "Invalid argument type for `message` for validator `{}` on field `{}`: only a string is allowed", + validator_name, field + ), + }; + } + _ => continue, + } + } } |
