From 9ef25eaff7b78c84816c920bce7da989284ef553 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Sat, 6 Jan 2024 23:42:39 +0900 Subject: [PATCH 1/6] refactor: update hint. --- .../src/validate/meta/meta_list.rs | 1 - .../src/validate/meta/nested_meta_list.rs | 48 ++++++++++++------- .../validate/meta/nested_meta_name_value.rs | 44 +++++++++++------ .../src/validate/meta/nested_meta_path.rs | 1 + 4 files changed, 62 insertions(+), 32 deletions(-) diff --git a/serde_valid_derive/src/validate/meta/meta_list.rs b/serde_valid_derive/src/validate/meta/meta_list.rs index bc0b0b6a..0ff8a2a6 100644 --- a/serde_valid_derive/src/validate/meta/meta_list.rs +++ b/serde_valid_derive/src/validate/meta/meta_list.rs @@ -50,7 +50,6 @@ pub fn extract_validator_from_meta_list( } syn::Meta::NameValue(name_value) => extract_validator_from_nested_meta_name_value( field, - attribute, name_value, custom_message, rename_map, diff --git a/serde_valid_derive/src/validate/meta/nested_meta_list.rs b/serde_valid_derive/src/validate/meta/nested_meta_list.rs index 828a0b7d..f37b0610 100644 --- a/serde_valid_derive/src/validate/meta/nested_meta_list.rs +++ b/serde_valid_derive/src/validate/meta/nested_meta_list.rs @@ -4,34 +4,48 @@ use crate::validate::common::{CustomMessageToken, MetaListValidation}; use crate::validate::generic::{ extract_generic_custom_validator, extract_generic_enumerate_validator, }; -use crate::validate::Validator; +use crate::validate::{MetaNameValueValidation, MetaPathValidation, Validator}; use std::str::FromStr; pub fn extract_validator_from_nested_meta_list( field: &impl Field, - validation_list: &syn::MetaList, + validation: &syn::MetaList, custom_message: CustomMessageToken, rename_map: &RenameMap, ) -> Result { - let syn::MetaList { - path: validation_name, - .. - } = validation_list; - let validation_ident = SingleIdentPath::new(validation_name).ident(); + let mut errors = vec![]; - match MetaListValidation::from_str(&validation_ident.to_string()) { + let validation_ident = SingleIdentPath::new(&validation.path).ident(); + let validation_name = validation_ident.to_string(); + + match MetaListValidation::from_str(&validation_name) { Ok(MetaListValidation::Enumerate) => { - extract_generic_enumerate_validator(field, validation_list, custom_message, rename_map) + extract_generic_enumerate_validator(field, validation, custom_message, rename_map) } Ok(MetaListValidation::Custom) => { - extract_generic_custom_validator(field, validation_list, rename_map) + extract_generic_custom_validator(field, validation, rename_map) + } + Err(unknown) => { + let error = if MetaNameValueValidation::from_str(&validation_name).is_ok() { + crate::Error::validate_meta_name_value_need_value( + &validation.path, + &validation_name, + ) + } else if MetaPathValidation::from_str(&validation_name).is_ok() { + crate::Error::validate_meta_path_need_value(&validation.path, &validation_name) + } else { + crate::Error::validate_unknown_type( + &validation.path, + &unknown, + &(MetaPathValidation::iter().map(|x| x.name())) + .chain(MetaNameValueValidation::iter().map(|x| x.name())) + .chain(MetaListValidation::iter().map(|x| x.name())) + .collect::>(), + ) + }; + errors.push(error); + + Err(errors) } - Err(unknown) => Err(vec![crate::Error::validate_unknown_type( - validation_name, - &unknown, - &MetaListValidation::iter() - .map(|x| x.name()) - .collect::>(), - )]), } } diff --git a/serde_valid_derive/src/validate/meta/nested_meta_name_value.rs b/serde_valid_derive/src/validate/meta/nested_meta_name_value.rs index 326a2573..044c1b28 100644 --- a/serde_valid_derive/src/validate/meta/nested_meta_name_value.rs +++ b/serde_valid_derive/src/validate/meta/nested_meta_name_value.rs @@ -16,21 +16,22 @@ use crate::validate::string::{ extract_string_max_length_validator, extract_string_min_length_validator, extract_string_pattern_validator, }; -use crate::validate::Validator; +use crate::validate::{MetaListValidation, MetaPathValidation, Validator}; use std::str::FromStr; pub fn extract_validator_from_nested_meta_name_value( field: &impl Field, - _attribute: &syn::Attribute, - name_value: &syn::MetaNameValue, + validation: &syn::MetaNameValue, custom_message: CustomMessageToken, rename_map: &RenameMap, ) -> Result { - let validation_name = &name_value.path; - let validation_name_ident = SingleIdentPath::new(validation_name).ident(); - let validation_value = get_lit(&name_value.value)?; + let mut errors = vec![]; - match MetaNameValueValidation::from_str(&validation_name_ident.to_string()) { + let validation_ident = SingleIdentPath::new(&validation.path).ident(); + let validation_name = validation_ident.to_string(); + let validation_value = get_lit(&validation.value)?; + + match MetaNameValueValidation::from_str(&validation_name) { Ok(MetaNameValueValidation::Minimum) => { extract_numeric_minimum_validator(field, validation_value, custom_message, rename_map) } @@ -86,12 +87,27 @@ pub fn extract_validator_from_nested_meta_name_value( Ok(MetaNameValueValidation::Pattern) => { extract_string_pattern_validator(field, validation_value, custom_message, rename_map) } - Err(unknown) => Err(vec![crate::Error::validate_unknown_type( - validation_name, - &unknown, - &MetaNameValueValidation::iter() - .map(|x| x.name()) - .collect::>(), - )]), + Err(unknown) => { + let error = if MetaListValidation::from_str(&validation_name).is_ok() { + crate::Error::validate_meta_name_value_need_value( + &validation.path, + &validation_name, + ) + } else if MetaPathValidation::from_str(&validation_name).is_ok() { + crate::Error::validate_meta_path_need_value(&validation.path, &validation_name) + } else { + crate::Error::validate_unknown_type( + &validation.path, + &unknown, + &(MetaPathValidation::iter().map(|x| x.name())) + .chain(MetaNameValueValidation::iter().map(|x| x.name())) + .chain(MetaListValidation::iter().map(|x| x.name())) + .collect::>(), + ) + }; + errors.push(error); + + Err(errors) + } } } diff --git a/serde_valid_derive/src/validate/meta/nested_meta_path.rs b/serde_valid_derive/src/validate/meta/nested_meta_path.rs index a47f1ba7..60995e12 100644 --- a/serde_valid_derive/src/validate/meta/nested_meta_path.rs +++ b/serde_valid_derive/src/validate/meta/nested_meta_path.rs @@ -14,6 +14,7 @@ pub fn extract_validator_from_nested_meta_path( rename_map: &RenameMap, ) -> Result { let mut errors = vec![]; + let validation_ident = SingleIdentPath::new(validation).ident(); let validation_name = validation_ident.to_string(); From 9b133181cea828ec30b3ab40b69e10c856e2b90d Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Sun, 7 Jan 2024 00:17:33 +0900 Subject: [PATCH 2/6] refactor: validation error handling. --- .../src/validate/generic/enumerate.rs | 3 +- .../src/validate/meta/meta_list.rs | 76 ++++++++++++++--- .../src/validate/meta/nested_meta_list.rs | 39 ++------- .../validate/meta/nested_meta_name_value.rs | 82 ++++++------------- .../src/validate/meta/nested_meta_path.rs | 38 ++------- 5 files changed, 102 insertions(+), 136 deletions(-) diff --git a/serde_valid_derive/src/validate/generic/enumerate.rs b/serde_valid_derive/src/validate/generic/enumerate.rs index b73ea85c..9d1252d7 100644 --- a/serde_valid_derive/src/validate/generic/enumerate.rs +++ b/serde_valid_derive/src/validate/generic/enumerate.rs @@ -2,7 +2,6 @@ use crate::serde::rename::RenameMap; use crate::types::Field; use crate::validate::common::CustomMessageToken; use crate::validate::Validator; -use proc_macro2::TokenStream; use quote::quote; type Lits<'a> = syn::punctuated::Punctuated; @@ -21,7 +20,7 @@ fn inner_extract_generic_enumerate_validator( item_list: &syn::MetaList, custom_message: CustomMessageToken, rename_map: &RenameMap, -) -> Result { +) -> Result { let field_name = field.name(); let field_ident = field.ident(); let field_key = field.key(); diff --git a/serde_valid_derive/src/validate/meta/meta_list.rs b/serde_valid_derive/src/validate/meta/meta_list.rs index 0ff8a2a6..416c64ee 100644 --- a/serde_valid_derive/src/validate/meta/meta_list.rs +++ b/serde_valid_derive/src/validate/meta/meta_list.rs @@ -2,9 +2,10 @@ use super::nested_meta_list::extract_validator_from_nested_meta_list; use super::nested_meta_name_value::extract_validator_from_nested_meta_name_value; use super::nested_meta_path::extract_validator_from_nested_meta_path; use crate::serde::rename::RenameMap; -use crate::types::Field; +use crate::types::{Field, SingleIdentPath}; use crate::validate::common::{extract_custom_message_tokens, CustomMessageToken}; -use crate::validate::Validator; +use crate::validate::{MetaListValidation, MetaNameValueValidation, MetaPathValidation, Validator}; +use std::str::FromStr; pub fn extract_validator_from_meta_list( field: &impl Field, @@ -41,20 +42,69 @@ pub fn extract_validator_from_meta_list( if !nested.is_empty() { let meta = &nested[0]; - let validator = match meta { - syn::Meta::Path(path) => { - extract_validator_from_nested_meta_path(field, path, custom_message, rename_map) + let validation_path = match meta { + syn::Meta::Path(path) => path, + syn::Meta::List(list) => &list.path, + syn::Meta::NameValue(name_value) => &name_value.path, + }; + + let validation_name = SingleIdentPath::new(validation_path).ident().to_string(); + + let validator = match ( + MetaPathValidation::from_str(&validation_name), + MetaListValidation::from_str(&validation_name), + MetaNameValueValidation::from_str(&validation_name), + meta, + ) { + (Ok(validation_type), _, _, syn::Meta::Path(path)) => { + extract_validator_from_nested_meta_path( + field, + validation_type, + path, + custom_message, + rename_map, + ) } - syn::Meta::List(list) => { - extract_validator_from_nested_meta_list(field, list, custom_message, rename_map) + (_, Ok(validation_type), _, syn::Meta::List(list)) => { + extract_validator_from_nested_meta_list( + field, + validation_type, + list, + custom_message, + rename_map, + ) } - syn::Meta::NameValue(name_value) => extract_validator_from_nested_meta_name_value( - field, - name_value, - custom_message, - rename_map, - ), + (_, _, Ok(validation_type), syn::Meta::NameValue(name_value)) => { + extract_validator_from_nested_meta_name_value( + field, + validation_type, + name_value, + custom_message, + rename_map, + ) + } + (Ok(_), _, _, _) => Err(vec![crate::Error::validate_meta_path_need_value( + validation_path, + &validation_name, + )]), + (_, Ok(_), _, _) => Err(vec![crate::Error::validate_meta_list_need_value( + validation_path, + &validation_name, + )]), + (_, _, Ok(_), _) => Err(vec![crate::Error::validate_meta_name_value_need_value( + validation_path, + &validation_name, + )]), + _ => Err(vec![crate::Error::validate_unknown_type( + validation_path, + &validation_name, + &(MetaPathValidation::iter().map(|x| x.name())) + .chain(MetaListValidation::iter().map(|x| x.name())) + .chain(MetaNameValueValidation::iter().map(|x| x.name())) + .collect::>(), + )]), }; + match validator { Ok(validator) => { if errors.is_empty() { diff --git a/serde_valid_derive/src/validate/meta/nested_meta_list.rs b/serde_valid_derive/src/validate/meta/nested_meta_list.rs index f37b0610..eea8920f 100644 --- a/serde_valid_derive/src/validate/meta/nested_meta_list.rs +++ b/serde_valid_derive/src/validate/meta/nested_meta_list.rs @@ -1,51 +1,24 @@ use crate::serde::rename::RenameMap; -use crate::types::{Field, SingleIdentPath}; +use crate::types::Field; use crate::validate::common::{CustomMessageToken, MetaListValidation}; use crate::validate::generic::{ extract_generic_custom_validator, extract_generic_enumerate_validator, }; -use crate::validate::{MetaNameValueValidation, MetaPathValidation, Validator}; -use std::str::FromStr; +use crate::validate::Validator; pub fn extract_validator_from_nested_meta_list( field: &impl Field, + validation_type: MetaListValidation, validation: &syn::MetaList, custom_message: CustomMessageToken, rename_map: &RenameMap, ) -> Result { - let mut errors = vec![]; - - let validation_ident = SingleIdentPath::new(&validation.path).ident(); - let validation_name = validation_ident.to_string(); - - match MetaListValidation::from_str(&validation_name) { - Ok(MetaListValidation::Enumerate) => { + match validation_type { + MetaListValidation::Enumerate => { extract_generic_enumerate_validator(field, validation, custom_message, rename_map) } - Ok(MetaListValidation::Custom) => { + MetaListValidation::Custom => { extract_generic_custom_validator(field, validation, rename_map) } - Err(unknown) => { - let error = if MetaNameValueValidation::from_str(&validation_name).is_ok() { - crate::Error::validate_meta_name_value_need_value( - &validation.path, - &validation_name, - ) - } else if MetaPathValidation::from_str(&validation_name).is_ok() { - crate::Error::validate_meta_path_need_value(&validation.path, &validation_name) - } else { - crate::Error::validate_unknown_type( - &validation.path, - &unknown, - &(MetaPathValidation::iter().map(|x| x.name())) - .chain(MetaNameValueValidation::iter().map(|x| x.name())) - .chain(MetaListValidation::iter().map(|x| x.name())) - .collect::>(), - ) - }; - errors.push(error); - - Err(errors) - } } } diff --git a/serde_valid_derive/src/validate/meta/nested_meta_name_value.rs b/serde_valid_derive/src/validate/meta/nested_meta_name_value.rs index 044c1b28..bd16666a 100644 --- a/serde_valid_derive/src/validate/meta/nested_meta_name_value.rs +++ b/serde_valid_derive/src/validate/meta/nested_meta_name_value.rs @@ -1,5 +1,5 @@ use crate::serde::rename::RenameMap; -use crate::types::{Field, SingleIdentPath}; +use crate::types::Field; use crate::validate::array::{ extract_array_max_items_validator, extract_array_min_items_validator, }; @@ -16,98 +16,68 @@ use crate::validate::string::{ extract_string_max_length_validator, extract_string_min_length_validator, extract_string_pattern_validator, }; -use crate::validate::{MetaListValidation, MetaPathValidation, Validator}; -use std::str::FromStr; +use crate::validate::Validator; pub fn extract_validator_from_nested_meta_name_value( field: &impl Field, + validation_type: MetaNameValueValidation, validation: &syn::MetaNameValue, custom_message: CustomMessageToken, rename_map: &RenameMap, ) -> Result { - let mut errors = vec![]; - - let validation_ident = SingleIdentPath::new(&validation.path).ident(); - let validation_name = validation_ident.to_string(); let validation_value = get_lit(&validation.value)?; - match MetaNameValueValidation::from_str(&validation_name) { - Ok(MetaNameValueValidation::Minimum) => { + match validation_type { + MetaNameValueValidation::Minimum => { extract_numeric_minimum_validator(field, validation_value, custom_message, rename_map) } - Ok(MetaNameValueValidation::Maximum) => { + MetaNameValueValidation::Maximum => { extract_numeric_maximum_validator(field, validation_value, custom_message, rename_map) } - Ok(MetaNameValueValidation::ExclusiveMinimum) => { - extract_numeric_exclusive_minimum_validator( - field, - validation_value, - custom_message, - rename_map, - ) - } - Ok(MetaNameValueValidation::ExclusiveMaximum) => { - extract_numeric_exclusive_maximum_validator( - field, - validation_value, - custom_message, - rename_map, - ) - } - Ok(MetaNameValueValidation::MinLength) => { + MetaNameValueValidation::ExclusiveMinimum => extract_numeric_exclusive_minimum_validator( + field, + validation_value, + custom_message, + rename_map, + ), + MetaNameValueValidation::ExclusiveMaximum => extract_numeric_exclusive_maximum_validator( + field, + validation_value, + custom_message, + rename_map, + ), + MetaNameValueValidation::MinLength => { extract_string_min_length_validator(field, validation_value, custom_message, rename_map) } - Ok(MetaNameValueValidation::MaxLength) => { + MetaNameValueValidation::MaxLength => { extract_string_max_length_validator(field, validation_value, custom_message, rename_map) } - Ok(MetaNameValueValidation::MinItems) => { + MetaNameValueValidation::MinItems => { extract_array_min_items_validator(field, validation_value, custom_message, rename_map) } - Ok(MetaNameValueValidation::MaxItems) => { + MetaNameValueValidation::MaxItems => { extract_array_max_items_validator(field, validation_value, custom_message, rename_map) } - Ok(MetaNameValueValidation::MinProperties) => extract_object_min_properties_validator( + MetaNameValueValidation::MinProperties => extract_object_min_properties_validator( field, validation_value, custom_message, rename_map, ), - Ok(MetaNameValueValidation::MaxProperties) => extract_object_max_properties_validator( + MetaNameValueValidation::MaxProperties => extract_object_max_properties_validator( field, validation_value, custom_message, rename_map, ), - Ok(MetaNameValueValidation::MultipleOf) => extract_numeric_multiple_of_validator( + MetaNameValueValidation::MultipleOf => extract_numeric_multiple_of_validator( field, validation_value, custom_message, rename_map, ), - Ok(MetaNameValueValidation::Pattern) => { + MetaNameValueValidation::Pattern => { extract_string_pattern_validator(field, validation_value, custom_message, rename_map) } - Err(unknown) => { - let error = if MetaListValidation::from_str(&validation_name).is_ok() { - crate::Error::validate_meta_name_value_need_value( - &validation.path, - &validation_name, - ) - } else if MetaPathValidation::from_str(&validation_name).is_ok() { - crate::Error::validate_meta_path_need_value(&validation.path, &validation_name) - } else { - crate::Error::validate_unknown_type( - &validation.path, - &unknown, - &(MetaPathValidation::iter().map(|x| x.name())) - .chain(MetaNameValueValidation::iter().map(|x| x.name())) - .chain(MetaListValidation::iter().map(|x| x.name())) - .collect::>(), - ) - }; - errors.push(error); - - Err(errors) - } } } diff --git a/serde_valid_derive/src/validate/meta/nested_meta_path.rs b/serde_valid_derive/src/validate/meta/nested_meta_path.rs index 60995e12..5fc819bf 100644 --- a/serde_valid_derive/src/validate/meta/nested_meta_path.rs +++ b/serde_valid_derive/src/validate/meta/nested_meta_path.rs @@ -1,47 +1,21 @@ use crate::serde::rename::RenameMap; -use crate::types::{Field, SingleIdentPath}; +use crate::types::Field; use crate::validate::array::extract_array_unique_items_validator; -use crate::validate::common::{ - CustomMessageToken, MetaListValidation, MetaNameValueValidation, MetaPathValidation, -}; +use crate::validate::common::{CustomMessageToken, MetaPathValidation}; use crate::validate::Validator; -use std::str::FromStr; pub fn extract_validator_from_nested_meta_path( field: &impl Field, - validation: &syn::Path, + validation_type: MetaPathValidation, + _validation: &syn::Path, custom_message: CustomMessageToken, rename_map: &RenameMap, ) -> Result { - let mut errors = vec![]; - - let validation_ident = SingleIdentPath::new(validation).ident(); - let validation_name = validation_ident.to_string(); - - match MetaPathValidation::from_str(&validation_name) { - Ok(MetaPathValidation::UniqueItems) => Ok(extract_array_unique_items_validator( + match validation_type { + MetaPathValidation::UniqueItems => Ok(extract_array_unique_items_validator( field, custom_message, rename_map, )), - Err(unknown) => { - let error = if MetaNameValueValidation::from_str(&validation_name).is_ok() { - crate::Error::validate_meta_name_value_need_value(validation, &validation_name) - } else if MetaListValidation::from_str(&validation_name).is_ok() { - crate::Error::validate_meta_list_need_value(validation, &validation_name) - } else { - crate::Error::validate_unknown_type( - validation, - &unknown, - &(MetaPathValidation::iter().map(|x| x.name())) - .chain(MetaNameValueValidation::iter().map(|x| x.name())) - .chain(MetaListValidation::iter().map(|x| x.name())) - .collect::>(), - ) - }; - errors.push(error); - - Err(errors) - } } } From 50a969c189d00abf3ce1bcb6acb5f7c9dc233234 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Sun, 7 Jan 2024 00:18:08 +0900 Subject: [PATCH 3/6] style: add newline. --- serde_valid_derive/src/validate/meta/meta_list.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/serde_valid_derive/src/validate/meta/meta_list.rs b/serde_valid_derive/src/validate/meta/meta_list.rs index 416c64ee..1240e046 100644 --- a/serde_valid_derive/src/validate/meta/meta_list.rs +++ b/serde_valid_derive/src/validate/meta/meta_list.rs @@ -65,6 +65,7 @@ pub fn extract_validator_from_meta_list( rename_map, ) } + (_, Ok(validation_type), _, syn::Meta::List(list)) => { extract_validator_from_nested_meta_list( field, @@ -74,6 +75,7 @@ pub fn extract_validator_from_meta_list( rename_map, ) } + (_, _, Ok(validation_type), syn::Meta::NameValue(name_value)) => { extract_validator_from_nested_meta_name_value( field, @@ -83,18 +85,22 @@ pub fn extract_validator_from_meta_list( rename_map, ) } + (Ok(_), _, _, _) => Err(vec![crate::Error::validate_meta_path_need_value( validation_path, &validation_name, )]), + (_, Ok(_), _, _) => Err(vec![crate::Error::validate_meta_list_need_value( validation_path, &validation_name, )]), + (_, _, Ok(_), _) => Err(vec![crate::Error::validate_meta_name_value_need_value( validation_path, &validation_name, )]), + _ => Err(vec![crate::Error::validate_unknown_type( validation_path, &validation_name, From 96805ca6497619424104deb508c8a6553db681c9 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Sun, 7 Jan 2024 00:21:41 +0900 Subject: [PATCH 4/6] fix: error message bug. --- serde_valid_derive/src/validate/meta/meta_list.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde_valid_derive/src/validate/meta/meta_list.rs b/serde_valid_derive/src/validate/meta/meta_list.rs index 1240e046..a3954ecc 100644 --- a/serde_valid_derive/src/validate/meta/meta_list.rs +++ b/serde_valid_derive/src/validate/meta/meta_list.rs @@ -32,7 +32,7 @@ pub fn extract_validator_from_meta_list( } }, _ => { - for meta in nested.iter().skip(1) { + for meta in nested.iter().skip(2) { errors.push(crate::Error::too_many_list_items(meta)); } CustomMessageToken::default() From 6bf3e30a6707c1f6c4123887e9b44f0eab9780ba Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Sun, 7 Jan 2024 00:48:48 +0900 Subject: [PATCH 5/6] refactor: custom message. --- serde_valid_derive/src/error.rs | 64 ++++++++-- serde_valid_derive/src/validate.rs | 2 +- serde_valid_derive/src/validate/common.rs | 20 ++-- .../src/validate/common/custom_message.rs | 113 ++++++++++-------- .../src/validate/meta/meta_list.rs | 20 ++-- 5 files changed, 140 insertions(+), 79 deletions(-) diff --git a/serde_valid_derive/src/error.rs b/serde_valid_derive/src/error.rs index 7d7a52aa..0a9c8820 100644 --- a/serde_valid_derive/src/error.rs +++ b/serde_valid_derive/src/error.rs @@ -5,7 +5,7 @@ use syn::spanned::Spanned; use crate::types::CommaSeparatedNestedMetas; #[cfg(feature = "fluent")] -use crate::validate::MetaListMessage; +use crate::validate::MetaListCustomMessage; pub fn object_errors_tokens() -> TokenStream { quote!(::serde_valid::validation::Errors::Object( @@ -213,27 +213,57 @@ impl Error { ) } - pub fn validate_meta_name_value_need_value(path: &syn::Path, validation_type: &str) -> Self { + pub fn meta_path_validation_need_value(path: &syn::Path, validation_type: &str) -> Self { Self::new( path.span(), - format!("#[validate({validation_type} = ???)] needs validation value."), + format!("#[validate({validation_type}(???))] needs validation path."), ) } - pub fn validate_meta_path_need_value(path: &syn::Path, validation_type: &str) -> Self { + pub fn meta_path_custom_message_need_value( + path: &syn::Path, + custom_message_type: &str, + ) -> Self { Self::new( path.span(), - format!("#[validate({validation_type}(???))] needs validation path."), + format!("#[validate(..., {custom_message_type}(???))] needs custom message path."), ) } - pub fn validate_meta_list_need_value(path: &syn::Path, validation_type: &str) -> Self { + pub fn meta_list_validation_need_value(path: &syn::Path, validation_type: &str) -> Self { Self::new( path.span(), format!("#[validate({validation_type}(???, ...))] needs validation list."), ) } + pub fn meta_list_custom_message_need_value( + path: &syn::Path, + custom_message_type: &str, + ) -> Self { + Self::new( + path.span(), + format!("#[validate(..., {custom_message_type}(???, ...))] needs custom message list."), + ) + } + + pub fn meta_name_value_validation_need_value(path: &syn::Path, validation_type: &str) -> Self { + Self::new( + path.span(), + format!("#[validate({validation_type} = ???)] needs validation value."), + ) + } + + pub fn meta_name_value_custom_message_need_value( + path: &syn::Path, + validation_type: &str, + ) -> Self { + Self::new( + path.span(), + format!("#[validate(..., {validation_type} = ???)] needs custom message value."), + ) + } + pub fn validate_attribute_parse_error(attribute: &syn::Attribute, error: &syn::Error) -> Self { Self::new( attribute.span(), @@ -253,7 +283,7 @@ impl Error { ) } - pub fn validate_unknown_type(path: &syn::Path, unknown: &str, candidates: &[&str]) -> Self { + pub fn unknown_validation_type(path: &syn::Path, unknown: &str, candidates: &[&str]) -> Self { let filterd_candidates = did_you_mean(unknown, candidates).unwrap_or_else(|| candidates.to_vec()); @@ -263,6 +293,20 @@ impl Error { ) } + pub fn unknown_custom_message_type( + path: &syn::Path, + unknown: &str, + candidates: &[&str], + ) -> Self { + let filterd_candidates = + did_you_mean(unknown, candidates).unwrap_or_else(|| candidates.to_vec()); + + Self::new( + path.span(), + format!("Unknown: `{unknown}` error message type. Is it one of the following?\n{filterd_candidates:#?}"), + ) + } + pub fn validate_enumerate_parse_error(path: &syn::Path, error: &syn::Error) -> Self { Self::new( path.span(), @@ -294,7 +338,7 @@ impl Error { } #[cfg(feature = "fluent")] - pub fn fluent_need_item(message_type: &MetaListMessage, path: &syn::Path) -> Self { + pub fn fluent_need_item(message_type: &MetaListCustomMessage, path: &syn::Path) -> Self { Self::new( path.span(), format!("`{}` need items.", message_type.name()), @@ -303,7 +347,7 @@ impl Error { #[cfg(feature = "fluent")] pub fn fluent_allow_key( - message_type: &MetaListMessage, + message_type: &MetaListCustomMessage, nested_meta: &crate::types::NestedMeta, ) -> Self { Self::new( @@ -324,7 +368,7 @@ impl Error { #[cfg(feature = "fluent")] pub fn fluent_allow_args( - message_type: &MetaListMessage, + message_type: &MetaListCustomMessage, nested_meta: &crate::types::NestedMeta, ) -> Self { Self::new( diff --git a/serde_valid_derive/src/validate.rs b/serde_valid_derive/src/validate.rs index 6bfea743..0cc74947 100644 --- a/serde_valid_derive/src/validate.rs +++ b/serde_valid_derive/src/validate.rs @@ -13,4 +13,4 @@ pub use field::{FieldValidators, Validator}; pub use meta::extract_meta_validator; #[cfg(feature = "fluent")] -pub use common::MetaListMessage; +pub use common::MetaListCustomMessage; diff --git a/serde_valid_derive/src/validate/common.rs b/serde_valid_derive/src/validate/common.rs index 31ff8370..ca116315 100644 --- a/serde_valid_derive/src/validate/common.rs +++ b/serde_valid_derive/src/validate/common.rs @@ -67,6 +67,12 @@ macro_rules! enum_str { }; } +enum_str! { + pub enum MetaPathValidation { + UniqueItems = "unique_items", + } +} + enum_str! { pub enum MetaListValidation { Enumerate = "enumerate", @@ -92,21 +98,20 @@ enum_str! { } enum_str! { - pub enum MetaPathValidation { - UniqueItems = "unique_items", + pub enum MetaPathCustomMessage { } } #[cfg(not(feature = "fluent"))] enum_str! { - pub enum MetaListMessage { + pub enum MetaListCustomMessage { MessageFn = "message_fn", } } #[cfg(feature = "fluent")] enum_str! { - pub enum MetaListMessage { + pub enum MetaListCustomMessage { MessageFn = "message_fn", I18n = "i18n", Fluent = "fluent", @@ -114,12 +119,7 @@ enum_str! { } enum_str! { - pub enum MetaNameValueMessage { + pub enum MetaNameValueCustomMessage { Message = "message", } } - -enum_str! { - pub enum MetaPathMessage { - } -} diff --git a/serde_valid_derive/src/validate/common/custom_message.rs b/serde_valid_derive/src/validate/common/custom_message.rs index 1e5e86ad..028cceb3 100644 --- a/serde_valid_derive/src/validate/common/custom_message.rs +++ b/serde_valid_derive/src/validate/common/custom_message.rs @@ -3,7 +3,7 @@ use proc_macro2::TokenStream; use quote::quote; use std::str::FromStr; -use super::{get_str, MetaListMessage, MetaNameValueMessage, MetaPathMessage}; +use super::{get_str, MetaListCustomMessage, MetaNameValueCustomMessage, MetaPathCustomMessage}; #[derive(Debug, Default)] pub struct CustomMessageToken { @@ -51,37 +51,52 @@ impl CustomMessageToken { pub fn extract_custom_message_tokens( meta: &syn::Meta, ) -> Result { - match meta { - syn::Meta::List(message_fn_list) => { - extract_custom_message_tokens_from_meta_list(message_fn_list) + let custom_message_path = match meta { + syn::Meta::Path(path) => path, + syn::Meta::List(list) => &list.path, + syn::Meta::NameValue(name_value) => &name_value.path, + }; + let custom_message_name = SingleIdentPath::new(custom_message_path) + .ident() + .to_string(); + + match ( + MetaPathCustomMessage::from_str(&custom_message_name), + MetaListCustomMessage::from_str(&custom_message_name), + MetaNameValueCustomMessage::from_str(&custom_message_name), + meta, + ) { + (Ok(_), _, _, syn::Meta::Path(_)) => { + unreachable!() } - syn::Meta::NameValue(name_value) => { - extract_custom_message_tokens_from_name_value(name_value) + (_, Ok(_), _, syn::Meta::List(custom_message)) => { + extract_custom_message_tokens_from_meta_list(custom_message) } - syn::Meta::Path(path) => { - let path_label = SingleIdentPath::new(path).ident().to_string(); - if MetaNameValueMessage::from_str(&path_label).is_ok() { - Err(crate::Error::validate_meta_name_value_need_value( - path, - &path_label, - )) - } else if MetaListMessage::from_str(&path_label).is_ok() { - Err(crate::Error::validate_meta_list_need_value( - path, - &path_label, - )) - } else { - Err(crate::Error::validate_unknown_type( - path, - &path_label, - &(MetaNameValueMessage::iter().map(|x| x.name())) - .chain(MetaListMessage::iter().map(|x| x.name())) - .chain(MetaPathMessage::iter().map(|x| x.name())) - .collect::>(), - )) - } + (_, _, Ok(_), syn::Meta::NameValue(custom_message)) => { + extract_custom_message_tokens_from_name_value(custom_message) } - .map_err(|error| vec![error]), + (Ok(_), _, _, _) => Err(vec![crate::Error::meta_path_custom_message_need_value( + custom_message_path, + &custom_message_name, + )]), + (_, Ok(_), _, _) => Err(vec![crate::Error::meta_list_custom_message_need_value( + custom_message_path, + &custom_message_name, + )]), + (_, _, Ok(_), _) => Err(vec![ + crate::Error::meta_name_value_custom_message_need_value( + custom_message_path, + &custom_message_name, + ), + ]), + _ => Err(vec![crate::Error::unknown_custom_message_type( + custom_message_path, + &custom_message_name, + &(MetaPathCustomMessage::iter().map(|x| x.name())) + .chain(MetaListCustomMessage::iter().map(|x| x.name())) + .chain(MetaNameValueCustomMessage::iter().map(|x| x.name())) + .collect::>(), + )]), } } @@ -95,24 +110,26 @@ fn extract_custom_message_tokens_from_meta_list( .parse_args_with(CommaSeparatedNestedMetas::parse_terminated) .map_err(|error| vec![crate::Error::message_fn_parse_error(path_ident, &error)])?; - match MetaListMessage::from_str(&path_label) { - Ok(MetaListMessage::MessageFn) => get_message_fn_from_nested_meta(path, &message_fn_define) - .map(CustomMessageToken::new_message_fn), + match MetaListCustomMessage::from_str(&path_label) { + Ok(MetaListCustomMessage::MessageFn) => { + get_message_fn_from_nested_meta(path, &message_fn_define) + .map(CustomMessageToken::new_message_fn) + } #[cfg(feature = "fluent")] - Ok(ref message_type @ (MetaListMessage::I18n | MetaListMessage::Fluent)) => { + Ok(ref message_type @ (MetaListCustomMessage::I18n | MetaListCustomMessage::Fluent)) => { get_fluent_message_from_nested_meta(message_type, path, &message_fn_define) .map(CustomMessageToken::new_fluent_message) } Err(unknown) => { - let error = if MetaNameValueMessage::from_str(&path_label).is_ok() { - crate::Error::validate_meta_list_need_value(path, &path_label) - } else if MetaPathMessage::from_str(&path_label).is_ok() { - crate::Error::validate_meta_path_need_value(path, &path_label) + let error = if MetaNameValueCustomMessage::from_str(&path_label).is_ok() { + crate::Error::meta_list_validation_need_value(path, &path_label) + } else if MetaPathCustomMessage::from_str(&path_label).is_ok() { + crate::Error::meta_path_validation_need_value(path, &path_label) } else { - crate::Error::validate_unknown_type( + crate::Error::unknown_validation_type( path, &unknown, - &MetaListMessage::iter() + &MetaListCustomMessage::iter() .map(|x| x.name()) .collect::>(), ) @@ -129,25 +146,25 @@ fn extract_custom_message_tokens_from_name_value( let path_ident = SingleIdentPath::new(path).ident(); let path_label = path_ident.to_string(); - match MetaNameValueMessage::from_str(&path_label) { - Ok(MetaNameValueMessage::Message) => { + match MetaNameValueCustomMessage::from_str(&path_label) { + Ok(MetaNameValueCustomMessage::Message) => { get_message_from_expr(&name_value.value).map(CustomMessageToken::new_message_fn) } - Err(unknown) => if MetaListMessage::from_str(&path_label).is_ok() { - Err(crate::Error::validate_meta_list_need_value( + Err(unknown) => if MetaListCustomMessage::from_str(&path_label).is_ok() { + Err(crate::Error::meta_list_validation_need_value( path, &path_label, )) - } else if MetaPathMessage::from_str(&path_label).is_ok() { - Err(crate::Error::validate_meta_path_need_value( + } else if MetaPathCustomMessage::from_str(&path_label).is_ok() { + Err(crate::Error::meta_path_validation_need_value( path, &path_label, )) } else { - Err(crate::Error::validate_unknown_type( + Err(crate::Error::unknown_validation_type( path, &unknown, - &MetaNameValueMessage::iter() + &MetaNameValueCustomMessage::iter() .map(|x| x.name()) .collect::>(), )) @@ -190,7 +207,7 @@ fn get_message_from_lit(lit: &syn::Lit) -> Result { #[cfg(feature = "fluent")] fn get_fluent_message_from_nested_meta( - message_type: &MetaListMessage, + message_type: &MetaListCustomMessage, path: &syn::Path, fn_define: &CommaSeparatedNestedMetas, ) -> Result { diff --git a/serde_valid_derive/src/validate/meta/meta_list.rs b/serde_valid_derive/src/validate/meta/meta_list.rs index a3954ecc..259154f4 100644 --- a/serde_valid_derive/src/validate/meta/meta_list.rs +++ b/serde_valid_derive/src/validate/meta/meta_list.rs @@ -56,52 +56,52 @@ pub fn extract_validator_from_meta_list( MetaNameValueValidation::from_str(&validation_name), meta, ) { - (Ok(validation_type), _, _, syn::Meta::Path(path)) => { + (Ok(validation_type), _, _, syn::Meta::Path(validation)) => { extract_validator_from_nested_meta_path( field, validation_type, - path, + validation, custom_message, rename_map, ) } - (_, Ok(validation_type), _, syn::Meta::List(list)) => { + (_, Ok(validation_type), _, syn::Meta::List(validation)) => { extract_validator_from_nested_meta_list( field, validation_type, - list, + validation, custom_message, rename_map, ) } - (_, _, Ok(validation_type), syn::Meta::NameValue(name_value)) => { + (_, _, Ok(validation_type), syn::Meta::NameValue(validation)) => { extract_validator_from_nested_meta_name_value( field, validation_type, - name_value, + validation, custom_message, rename_map, ) } - (Ok(_), _, _, _) => Err(vec![crate::Error::validate_meta_path_need_value( + (Ok(_), _, _, _) => Err(vec![crate::Error::meta_path_validation_need_value( validation_path, &validation_name, )]), - (_, Ok(_), _, _) => Err(vec![crate::Error::validate_meta_list_need_value( + (_, Ok(_), _, _) => Err(vec![crate::Error::meta_list_validation_need_value( validation_path, &validation_name, )]), - (_, _, Ok(_), _) => Err(vec![crate::Error::validate_meta_name_value_need_value( + (_, _, Ok(_), _) => Err(vec![crate::Error::meta_name_value_validation_need_value( validation_path, &validation_name, )]), - _ => Err(vec![crate::Error::validate_unknown_type( + _ => Err(vec![crate::Error::unknown_validation_type( validation_path, &validation_name, &(MetaPathValidation::iter().map(|x| x.name())) From de78c46f1ea36e07183d95e95b2261a8f95147c8 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Sun, 7 Jan 2024 00:56:49 +0900 Subject: [PATCH 6/6] refactor: custom message.x --- serde_valid_derive/src/error.rs | 24 ++++--- serde_valid_derive/src/validate.rs | 8 +-- .../src/validate/common/custom_message.rs | 65 ++++--------------- .../src/validate/meta/meta_list.rs | 4 -- 4 files changed, 31 insertions(+), 70 deletions(-) diff --git a/serde_valid_derive/src/error.rs b/serde_valid_derive/src/error.rs index 0a9c8820..06905a59 100644 --- a/serde_valid_derive/src/error.rs +++ b/serde_valid_derive/src/error.rs @@ -1,10 +1,12 @@ -use crate::validate::{MetaListValidation, MetaNameValueValidation, MetaPathValidation}; +use crate::validate::{ + MetaListValidation, MetaNameValueCustomMessage, MetaNameValueValidation, MetaPathCustomMessage, + MetaPathValidation, +}; use proc_macro2::TokenStream; use quote::quote; use syn::spanned::Spanned; use crate::types::CommaSeparatedNestedMetas; -#[cfg(feature = "fluent")] use crate::validate::MetaListCustomMessage; pub fn object_errors_tokens() -> TokenStream { @@ -283,7 +285,12 @@ impl Error { ) } - pub fn unknown_validation_type(path: &syn::Path, unknown: &str, candidates: &[&str]) -> Self { + pub fn unknown_validation_type(path: &syn::Path, unknown: &str) -> Self { + let candidates = &(MetaPathValidation::iter().map(|x| x.name())) + .chain(MetaListValidation::iter().map(|x| x.name())) + .chain(MetaNameValueValidation::iter().map(|x| x.name())) + .collect::>(); + let filterd_candidates = did_you_mean(unknown, candidates).unwrap_or_else(|| candidates.to_vec()); @@ -293,11 +300,12 @@ impl Error { ) } - pub fn unknown_custom_message_type( - path: &syn::Path, - unknown: &str, - candidates: &[&str], - ) -> Self { + pub fn unknown_custom_message_type(path: &syn::Path, unknown: &str) -> Self { + let candidates = &(MetaPathCustomMessage::iter().map(|x| x.name())) + .chain(MetaListCustomMessage::iter().map(|x| x.name())) + .chain(MetaNameValueCustomMessage::iter().map(|x| x.name())) + .collect::>(); + let filterd_candidates = did_you_mean(unknown, candidates).unwrap_or_else(|| candidates.to_vec()); diff --git a/serde_valid_derive/src/validate.rs b/serde_valid_derive/src/validate.rs index 0cc74947..3612c880 100644 --- a/serde_valid_derive/src/validate.rs +++ b/serde_valid_derive/src/validate.rs @@ -7,10 +7,10 @@ mod numeric; mod object; mod string; -pub use common::{MetaListValidation, MetaNameValueValidation, MetaPathValidation}; +pub use common::{ + MetaListCustomMessage, MetaListValidation, MetaNameValueCustomMessage, MetaNameValueValidation, + MetaPathCustomMessage, MetaPathValidation, +}; pub use field::{FieldValidators, Validator}; pub use meta::extract_meta_validator; - -#[cfg(feature = "fluent")] -pub use common::MetaListCustomMessage; diff --git a/serde_valid_derive/src/validate/common/custom_message.rs b/serde_valid_derive/src/validate/common/custom_message.rs index 028cceb3..8d15edab 100644 --- a/serde_valid_derive/src/validate/common/custom_message.rs +++ b/serde_valid_derive/src/validate/common/custom_message.rs @@ -69,11 +69,11 @@ pub fn extract_custom_message_tokens( (Ok(_), _, _, syn::Meta::Path(_)) => { unreachable!() } - (_, Ok(_), _, syn::Meta::List(custom_message)) => { - extract_custom_message_tokens_from_meta_list(custom_message) + (_, Ok(custom_message_type), _, syn::Meta::List(custom_message)) => { + extract_custom_message_tokens_from_meta_list(&custom_message_type, custom_message) } - (_, _, Ok(_), syn::Meta::NameValue(custom_message)) => { - extract_custom_message_tokens_from_name_value(custom_message) + (_, _, Ok(custom_message_type), syn::Meta::NameValue(custom_message)) => { + extract_custom_message_tokens_from_name_value(&custom_message_type, custom_message) } (Ok(_), _, _, _) => Err(vec![crate::Error::meta_path_custom_message_need_value( custom_message_path, @@ -92,84 +92,41 @@ pub fn extract_custom_message_tokens( _ => Err(vec![crate::Error::unknown_custom_message_type( custom_message_path, &custom_message_name, - &(MetaPathCustomMessage::iter().map(|x| x.name())) - .chain(MetaListCustomMessage::iter().map(|x| x.name())) - .chain(MetaNameValueCustomMessage::iter().map(|x| x.name())) - .collect::>(), )]), } } fn extract_custom_message_tokens_from_meta_list( + custom_message_type: &MetaListCustomMessage, meta_list: &syn::MetaList, ) -> Result { let path = &meta_list.path; let path_ident = SingleIdentPath::new(path).ident(); - let path_label = path_ident.to_string(); let message_fn_define = meta_list .parse_args_with(CommaSeparatedNestedMetas::parse_terminated) .map_err(|error| vec![crate::Error::message_fn_parse_error(path_ident, &error)])?; - match MetaListCustomMessage::from_str(&path_label) { - Ok(MetaListCustomMessage::MessageFn) => { + match custom_message_type { + MetaListCustomMessage::MessageFn => { get_message_fn_from_nested_meta(path, &message_fn_define) .map(CustomMessageToken::new_message_fn) } #[cfg(feature = "fluent")] - Ok(ref message_type @ (MetaListCustomMessage::I18n | MetaListCustomMessage::Fluent)) => { + message_type @ (MetaListCustomMessage::I18n | MetaListCustomMessage::Fluent) => { get_fluent_message_from_nested_meta(message_type, path, &message_fn_define) .map(CustomMessageToken::new_fluent_message) } - Err(unknown) => { - let error = if MetaNameValueCustomMessage::from_str(&path_label).is_ok() { - crate::Error::meta_list_validation_need_value(path, &path_label) - } else if MetaPathCustomMessage::from_str(&path_label).is_ok() { - crate::Error::meta_path_validation_need_value(path, &path_label) - } else { - crate::Error::unknown_validation_type( - path, - &unknown, - &MetaListCustomMessage::iter() - .map(|x| x.name()) - .collect::>(), - ) - }; - Err(vec![error]) - } } } fn extract_custom_message_tokens_from_name_value( + custom_message_type: &MetaNameValueCustomMessage, name_value: &syn::MetaNameValue, ) -> Result { - let path = &name_value.path; - let path_ident = SingleIdentPath::new(path).ident(); - let path_label = path_ident.to_string(); - - match MetaNameValueCustomMessage::from_str(&path_label) { - Ok(MetaNameValueCustomMessage::Message) => { + match custom_message_type { + MetaNameValueCustomMessage::Message => { get_message_from_expr(&name_value.value).map(CustomMessageToken::new_message_fn) } - Err(unknown) => if MetaListCustomMessage::from_str(&path_label).is_ok() { - Err(crate::Error::meta_list_validation_need_value( - path, - &path_label, - )) - } else if MetaPathCustomMessage::from_str(&path_label).is_ok() { - Err(crate::Error::meta_path_validation_need_value( - path, - &path_label, - )) - } else { - Err(crate::Error::unknown_validation_type( - path, - &unknown, - &MetaNameValueCustomMessage::iter() - .map(|x| x.name()) - .collect::>(), - )) - } - .map_err(|error| vec![error]), } } diff --git a/serde_valid_derive/src/validate/meta/meta_list.rs b/serde_valid_derive/src/validate/meta/meta_list.rs index 259154f4..a23d716a 100644 --- a/serde_valid_derive/src/validate/meta/meta_list.rs +++ b/serde_valid_derive/src/validate/meta/meta_list.rs @@ -104,10 +104,6 @@ pub fn extract_validator_from_meta_list( _ => Err(vec![crate::Error::unknown_validation_type( validation_path, &validation_name, - &(MetaPathValidation::iter().map(|x| x.name())) - .chain(MetaListValidation::iter().map(|x| x.name())) - .chain(MetaNameValueValidation::iter().map(|x| x.name())) - .collect::>(), )]), };