diff options
| author | Bastien Orivel | 2018-03-16 20:15:53 +0100 |
|---|---|---|
| committer | Bastien Orivel | 2018-03-16 20:17:36 +0100 |
| commit | b2cda48e139d5b599b813601ad806420f1f3757a (patch) | |
| tree | aaa0f3b1c554dbbac7b292b1e03b43472698c45d /validator_derive | |
| parent | c0dd8f2fc1ba45547102cecc12c3dc7bfe44f2d4 (diff) | |
| download | validator-b2cda48e139d5b599b813601ad806420f1f3757a.tar.bz2 | |
Bump syn to 0.12 and quote to 0.4
Diffstat (limited to 'validator_derive')
| -rw-r--r-- | validator_derive/Cargo.toml | 4 | ||||
| -rw-r--r-- | validator_derive/src/lib.rs | 163 | ||||
| -rw-r--r-- | validator_derive/src/lit.rs | 38 | ||||
| -rw-r--r-- | validator_derive/src/quoting.rs | 8 | ||||
| -rw-r--r-- | validator_derive/src/validation.rs | 70 |
5 files changed, 135 insertions, 148 deletions
diff --git a/validator_derive/Cargo.toml b/validator_derive/Cargo.toml index cd00a3a..3827490 100644 --- a/validator_derive/Cargo.toml +++ b/validator_derive/Cargo.toml @@ -15,8 +15,8 @@ proc-macro = true phone = ["validator/phone"] [dependencies] -syn = "0.11" -quote = "0.3" +syn = { version = "0.12", features = ["extra-traits"] } +quote = "0.4" if_chain = "0" validator = { version = "0.6", path = "../validator"} diff --git a/validator_derive/src/lib.rs b/validator_derive/src/lib.rs index 6700c2a..4aa37d0 100644 --- a/validator_derive/src/lib.rs +++ b/validator_derive/src/lib.rs @@ -4,6 +4,7 @@ #[macro_use] extern crate quote; extern crate proc_macro; +#[macro_use] extern crate syn; #[macro_use] extern crate if_chain; @@ -30,23 +31,21 @@ use quoting::{FieldQuoter, quote_field_validation, quote_schema_validation}; #[proc_macro_derive(Validate, attributes(validate))] pub fn derive_validation(input: TokenStream) -> TokenStream { - let source = input.to_string(); - // Parse the string representation to an AST - let ast = syn::parse_macro_input(&source).unwrap(); + let ast = syn::parse(input).unwrap(); let expanded = impl_validate(&ast); - expanded.parse().unwrap() + expanded.into() } -fn impl_validate(ast: &syn::MacroInput) -> quote::Tokens { +fn impl_validate(ast: &syn::DeriveInput) -> quote::Tokens { // Ensure the macro is on a struct with named fields - let fields = match ast.body { - syn::Body::Struct(syn::VariantData::Struct(ref fields)) => { + let fields = match ast.data { + syn::Data::Struct(syn::DataStruct { ref fields, .. }) => { if fields.iter().any(|field| field.ident.is_none()) { panic!("struct has unnamed fields"); } - fields + fields.iter().cloned().collect() }, _ => panic!("#[derive(Validate)] can only be used with structs"), }; @@ -55,7 +54,7 @@ fn impl_validate(ast: &syn::MacroInput) -> quote::Tokens { let field_types = find_fields_type(&fields); - for field in fields { + for field in &fields { let field_ident = field.ident.clone().unwrap(); let (name, field_validations) = find_validators_for_field(field, &field_types); let field_type = field_types.get(&field_ident.to_string()).cloned().unwrap(); @@ -102,17 +101,17 @@ fn find_struct_validation(struct_attrs: &Vec<syn::Attribute>) -> Option<SchemaVa }; for attr in struct_attrs { - if attr.value.name() != "validate" { + if attr.path != parse_quote!(validate) { continue; } if_chain! { - if let syn::MetaItem::List(_, ref meta_items) = attr.value; - if let syn::NestedMetaItem::MetaItem(ref item) = meta_items[0]; - if let &syn::MetaItem::List(ref ident2, ref args) = item; + if let Some(syn::Meta::List(syn::MetaList { ref nested, .. })) = attr.interpret_meta(); + if let syn::NestedMeta::Meta(ref item) = nested[0]; + if let &syn::Meta::List(syn::MetaList { ref ident, ref nested, .. }) = item; then { - if ident2 != "schema" { + if ident.as_ref() != "schema" { error("Only `schema` is allowed as validator on a struct") } @@ -121,36 +120,36 @@ fn find_struct_validation(struct_attrs: &Vec<syn::Attribute>) -> Option<SchemaVa let mut code = None; let mut message = None; - for arg in args { + for arg in nested { if_chain! { - if let syn::NestedMetaItem::MetaItem(ref item) = *arg; - if let syn::MetaItem::NameValue(ref name, ref val) = *item; + if let syn::NestedMeta::Meta(ref item) = *arg; + if let syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) = *item; then { - match name.to_string().as_ref() { + match ident.as_ref() { "function" => { - function = match lit_to_string(val) { + function = match lit_to_string(lit) { Some(s) => s, None => error("invalid argument type for `function` \ : only a string is allowed"), }; }, "skip_on_field_errors" => { - skip_on_field_errors = match lit_to_bool(val) { + skip_on_field_errors = match lit_to_bool(lit) { Some(s) => s, None => error("invalid argument type for `skip_on_field_errors` \ : only a bool is allowed"), }; }, "code" => { - code = match lit_to_string(val) { + code = match lit_to_string(lit) { Some(s) => Some(s), None => error("invalid argument type for `code` \ : only a string is allowed"), }; }, "message" => { - message = match lit_to_string(val) { + message = match lit_to_string(lit) { Some(s) => Some(s), None => error("invalid argument type for `message` \ : only a string is allowed"), @@ -194,17 +193,17 @@ fn find_fields_type(fields: &Vec<syn::Field>) -> HashMap<String, String> { for field in fields { let field_ident = field.ident.clone().unwrap().to_string(); let field_type = match field.ty { - syn::Ty::Path(_, ref p) => { + syn::Type::Path(syn::TypePath { ref path, .. }) => { let mut tokens = quote::Tokens::new(); - p.to_tokens(&mut tokens); + path.to_tokens(&mut tokens); tokens.to_string().replace(' ', "") }, - syn::Ty::Rptr(ref l, ref p) => { + syn::Type::Reference(syn::TypeReference { ref lifetime, ref elem, .. }) => { let mut tokens = quote::Tokens::new(); - p.ty.to_tokens(&mut tokens); + elem.to_tokens(&mut tokens); let mut name = tokens.to_string().replace(' ', ""); - if l.is_some() { + if lifetime.is_some() { name.insert(0, '&') } name @@ -235,19 +234,20 @@ fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, S let mut has_validate = false; for attr in &field.attrs { - if attr.name() != "validate" && attr.name() != "serde" { + if attr.path != parse_quote!(validate) && attr.path != parse_quote!(serde) { continue; } - if attr.name() == "validate" { + if attr.path == parse_quote!(validate) { has_validate = true; } - match attr.value { - syn::MetaItem::List(_, ref meta_items) => { + match attr.interpret_meta() { + Some(syn::Meta::List(syn::MetaList { ref nested, .. })) => { + let meta_items = nested.iter().collect(); // original name before serde rename - if attr.name() == "serde" { - if let Some(s) = find_original_field_name(meta_items) { + if attr.path == parse_quote!(serde) { + if let Some(s) = find_original_field_name(&meta_items) { field_ident = s; } continue; @@ -256,9 +256,9 @@ fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, S // only validation from there on for meta_item in meta_items { match *meta_item { - syn::NestedMetaItem::MetaItem(ref item) => match *item { + syn::NestedMeta::Meta(ref item) => match *item { // email, url, phone - syn::MetaItem::Word(ref name) => match name.to_string().as_ref() { + syn::Meta::Word(ref name) => match name.to_string().as_ref() { "email" => { assert_string_type("email", field_type); validators.push(FieldValidation::new(Validator::Email)); @@ -279,28 +279,28 @@ fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, S _ => panic!("Unexpected validator: {}", name) }, // custom, contains, must_match, regex - syn::MetaItem::NameValue(ref name, ref val) => { - match name.to_string().as_ref() { + syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) => { + match ident.as_ref() { "custom" => { - match lit_to_string(val) { + 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(val) { + 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(val) { + match lit_to_string(lit) { Some(s) => validators.push(FieldValidation::new(Validator::Regex(s))), None => error("invalid argument for `regex` validator: only strings are allowed"), }; } "must_match" => { - match lit_to_string(val) { + match lit_to_string(lit) { Some(s) => { assert_type_matches(rust_ident.clone(), field_type, field_types.get(&s)); validators.push(FieldValidation::new(Validator::MustMatch(s))); @@ -308,42 +308,45 @@ 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"), }; }, - _ => panic!("unexpected name value validator: {:?}", name), + v => panic!("unexpected name value validator: {:?}", v), }; }, // Validators with several args - syn::MetaItem::List(ref name, ref meta_items) => match name.to_string().as_ref() { - "length" => { - assert_has_len(rust_ident.clone(), field_type); - 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)); - }, - "email" | "url" | "phone" | "credit_card" => { - validators.push(extract_argless_validation(name.to_string(), rust_ident.clone(), meta_items)); - }, - "custom" => { - validators.push(extract_one_arg_validation("function", name.to_string(), rust_ident.clone(), meta_items)); - }, - "contains" => { - validators.push(extract_one_arg_validation("pattern", name.to_string(), rust_ident.clone(), meta_items)); - }, - "regex" => { - validators.push(extract_one_arg_validation("path", name.to_string(), rust_ident.clone(), meta_items)); - }, - "must_match" => { - let validation = extract_one_arg_validation("other", name.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)); - } - validators.push(validation); - }, - _ => panic!("unexpected list validator: {:?}", name.to_string()) + syn::Meta::List(syn::MetaList { ref ident, ref nested, .. }) => { + let meta_items = nested.iter().cloned().collect(); + match ident.as_ref() { + "length" => { + assert_has_len(rust_ident.clone(), field_type); + 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)); + }, + "email" | "url" | "phone" | "credit_card" => { + 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)); + }, + "contains" => { + 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)); + }, + "must_match" => { + 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)); + } + validators.push(validation); + }, + v => panic!("unexpected list validator: {:?}", v) + } }, }, - _ => unreachable!("Found a non MetaItem while looking for validators") + _ => unreachable!("Found a non Meta while looking for validators") }; } }, @@ -363,20 +366,20 @@ fn find_validators_for_field(field: &syn::Field, field_types: &HashMap<String, S /// /// For example a JS frontend might send camelCase fields and Rust converts them to snake_case /// but we want to send the errors back with the original name -fn find_original_field_name(meta_items: &Vec<syn::NestedMetaItem>) -> Option<String> { +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::NestedMetaItem::MetaItem(ref item) => match *item { - syn::MetaItem::Word(_) => continue, - syn::MetaItem::NameValue(ref name, ref val) => { - if name == "rename" { - original_name = Some(lit_to_string(val).unwrap()); + &syn::NestedMeta::Meta(ref item) => match *item { + syn::Meta::Word(_) => continue, + syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) => { + if ident.as_ref() == "rename" { + original_name = Some(lit_to_string(lit).unwrap()); } }, - syn::MetaItem::List(_, ref meta_items) => { - return find_original_field_name(meta_items); + syn::Meta::List(syn::MetaList { ref nested, .. }) => { + return find_original_field_name(&nested.iter().collect()); } }, _ => unreachable!() diff --git a/validator_derive/src/lit.rs b/validator_derive/src/lit.rs index 0753a17..839b62d 100644 --- a/validator_derive/src/lit.rs +++ b/validator_derive/src/lit.rs @@ -1,61 +1,45 @@ -use quote::{self, ToTokens}; +use quote; use syn; pub fn lit_to_string(lit: &syn::Lit) -> Option<String> { match *lit { - syn::Lit::Str(ref s, _) => Some(s.to_string()), + syn::Lit::Str(ref s) => Some(s.value()), _ => None, } } pub fn lit_to_int(lit: &syn::Lit) -> Option<u64> { match *lit { - syn::Lit::Int(ref s, _) => Some(*s), + syn::Lit::Int(ref s) => Some(s.value()), // TODO: remove when attr_literals is stable - syn::Lit::Str(ref s, _) => Some(s.parse::<u64>().unwrap()), + syn::Lit::Str(ref s) => Some(s.value().parse::<u64>().unwrap()), _ => None, } } pub fn lit_to_float(lit: &syn::Lit) -> Option<f64> { match *lit { - syn::Lit::Float(ref s, _) => Some(s.parse::<f64>().unwrap()), - syn::Lit::Int(ref s, _) => Some(*s as f64), + 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.parse::<f64>().unwrap()), + syn::Lit::Str(ref s) => Some(s.value().parse::<f64>().unwrap()), _ => None, } } pub fn lit_to_bool(lit: &syn::Lit) -> Option<bool> { match *lit { - syn::Lit::Bool(ref s) => Some(*s), + syn::Lit::Bool(ref s) => Some(s.value), // TODO: remove when attr_literals is stable - syn::Lit::Str(ref s, _) => if s == "true" { Some(true) } else { Some(false) }, + syn::Lit::Str(ref s) => if s.value() == "true" { Some(true) } else { Some(false) }, _ => None, } } pub fn option_u64_to_tokens(opt: Option<u64>) -> quote::Tokens { - let mut tokens = quote::Tokens::new(); - tokens.append("::"); - tokens.append("std"); - tokens.append("::"); - tokens.append("option"); - tokens.append("::"); - tokens.append("Option"); - tokens.append("::"); match opt { - Some(ref t) => { - tokens.append("Some"); - tokens.append("("); - t.to_tokens(&mut tokens); - tokens.append(")"); - } - None => { - tokens.append("None"); - } + Some(ref t) => quote!(::std::option::Option::Some(#t)), + None => quote!(::std::option::Option::None) } - tokens } diff --git a/validator_derive/src/quoting.rs b/validator_derive/src/quoting.rs index f7968e2..bf2a531 100644 --- a/validator_derive/src/quoting.rs +++ b/validator_derive/src/quoting.rs @@ -228,7 +228,7 @@ pub fn quote_must_match_validation(field_quoter: &FieldQuoter, validation: &Fiel let field_name = &field_quoter.name; if let Validator::MustMatch(ref other) = validation.validator { - let other_ident = syn::Ident::new(other.clone()); + let other_ident = syn::Ident::from(other.clone()); let quoted_error = quote_error(&validation); let quoted = quote!( if !::validator::validate_must_match(&self.#ident, &self.#other_ident) { @@ -250,7 +250,7 @@ pub fn quote_custom_validation(field_quoter: &FieldQuoter, validation: &FieldVal let validator_param = field_quoter.quote_validator_param(); if let Validator::Custom(ref fun) = validation.validator { - let fn_ident = syn::Ident::new(fun.clone()); + let fn_ident = syn::Ident::from(fun.clone()); let add_message_quoted = if let Some(ref m) = validation.message { quote!(err.message = Some(::std::borrow::Cow::from(#m));) } else { @@ -300,7 +300,7 @@ pub fn quote_regex_validation(field_quoter: &FieldQuoter, validation: &FieldVali let validator_param = field_quoter.quote_validator_param(); if let Validator::Regex(ref re) = validation.validator { - let re_ident = syn::Ident::new(re.clone()); + let re_ident = syn::Ident::from(re.clone()); let quoted_error = quote_error(&validation); let quoted = quote!( if !#re_ident.is_match(#validator_param) { @@ -335,7 +335,7 @@ pub fn quote_field_validation(field_quoter: &FieldQuoter, validation: &FieldVali pub fn quote_schema_validation(validation: Option<SchemaValidation>) -> quote::Tokens { if let Some(v) = validation { - let fn_ident = syn::Ident::new(v.function); + let fn_ident = syn::Ident::from(v.function); let add_message_quoted = if let Some(ref m) = v.message { quote!(err.message = Some(::std::borrow::Cow::from(#m));) diff --git a/validator_derive/src/validation.rs b/validator_derive/src/validation.rs index bbec9d6..b5c7b78 100644 --- a/validator_derive/src/validation.rs +++ b/validator_derive/src/validation.rs @@ -31,7 +31,7 @@ impl FieldValidation { } } -pub fn extract_length_validation(field: String, meta_items: &Vec<syn::NestedMetaItem>) -> 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; @@ -43,31 +43,31 @@ pub fn extract_length_validation(field: String, meta_items: &Vec<syn::NestedMeta }; for meta_item in meta_items { - if let syn::NestedMetaItem::MetaItem(ref item) = *meta_item { - if let syn::MetaItem::NameValue(ref name, ref val) = *item { - match name.to_string().as_ref() { + if let syn::NestedMeta::Meta(ref item) = *meta_item { + if let syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) = *item { + match ident.as_ref() { "message" | "code" => continue, "min" => { - min = match lit_to_int(val) { + 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(val) { + 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(val) { + equal = match lit_to_int(lit) { Some(s) => Some(s), None => error("invalid argument type for `equal` of `length` validator: only integers are allowed"), }; }, - _ => error(&format!( + v => error(&format!( "unknown argument `{}` for validator `length` (it only has `min`, `max`, `equal`)", - name.to_string() + v )) } } else { @@ -91,7 +91,7 @@ pub fn extract_length_validation(field: String, meta_items: &Vec<syn::NestedMeta } } -pub fn extract_range_validation(field: String, meta_items: &Vec<syn::NestedMetaItem>) -> FieldValidation { +pub fn extract_range_validation(field: String, meta_items: &Vec<syn::NestedMeta>) -> FieldValidation { let mut min = 0.0; let mut max = 0.0; @@ -107,27 +107,27 @@ pub fn extract_range_validation(field: String, meta_items: &Vec<syn::NestedMetaI for meta_item in meta_items { match *meta_item { - syn::NestedMetaItem::MetaItem(ref item) => match *item { - syn::MetaItem::NameValue(ref name, ref val) => { - match name.to_string().as_ref() { + syn::NestedMeta::Meta(ref item) => match *item { + syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) => { + match ident.as_ref() { "message" | "code" => continue, "min" => { - min = match lit_to_float(val) { + 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(val) { + 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; }, - _ => error(&format!( + v => error(&format!( "unknown argument `{}` for validator `range` (it only has `min`, `max`)", - name.to_string() + v )) } }, @@ -150,18 +150,18 @@ pub fn extract_range_validation(field: String, meta_items: &Vec<syn::NestedMetaI } /// 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::NestedMetaItem>) -> 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 { match *meta_item { - syn::NestedMetaItem::MetaItem(ref item) => match *item { - syn::MetaItem::NameValue(ref name, ref val) => { - match name.to_string().as_ref() { + syn::NestedMeta::Meta(ref item) => match *item { + syn::Meta::NameValue(syn::MetaNameValue { ref ident, .. }) => { + match ident.as_ref() { "message" | "code" => continue, - _ => panic!( + v => panic!( "Unknown argument `{}` for validator `{}` on field `{}`", - name.to_string(), validator_name, field + v, validator_name, field ) } }, @@ -187,18 +187,18 @@ 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::NestedMetaItem>) -> 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); for meta_item in meta_items { match *meta_item { - syn::NestedMetaItem::MetaItem(ref item) => match *item { - syn::MetaItem::NameValue(ref name, ref val) => { - match name.to_string().as_ref() { + syn::NestedMeta::Meta(ref item) => match *item { + syn::Meta::NameValue(syn::MetaNameValue { ref ident, ref lit, .. }) => { + match ident.as_ref() { "message" | "code" => continue, v if v == val_name => { - value = match lit_to_string(val) { + value = match lit_to_string(lit) { Some(s) => Some(s), None => panic!( "Invalid argument type for `{}` for validator `{}` on field `{}`: only a string is allowed", @@ -206,9 +206,9 @@ pub fn extract_one_arg_validation(val_name: &str, validator_name: String, field: ), }; }, - _ => panic!( + v => panic!( "Unknown argument `{}` for validator `{}` on field `{}`", - name.to_string(), validator_name, field + v, validator_name, field ) } }, @@ -237,15 +237,15 @@ 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::NestedMetaItem>) -> (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::NestedMetaItem::MetaItem(syn::MetaItem::NameValue(ref name, ref val)) = *meta_item { - match name.to_string().as_ref() { + if let syn::NestedMeta::Meta(syn::Meta::NameValue(syn::MetaNameValue { ref ident , ref lit, .. })) = *meta_item { + match ident.as_ref() { "code" => { - code = match lit_to_string(val) { + 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", @@ -254,7 +254,7 @@ fn extract_message_and_code(validator_name: &str, field: &str, meta_items: &Vec< }; }, "message" => { - message = match lit_to_string(val) { + 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", |
