From 8d0a59bfc900ba5e78057d6807d01ecac804fd37 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Thu, 11 Jan 2024 00:05:02 +0900 Subject: [PATCH 01/25] wip: add custom_message params. --- .../src/attribute/field_validate.rs | 7 +++--- .../src/attribute/struct_validate/meta.rs | 25 ++++++++++++++----- .../struct_validate/meta/meta_list.rs | 3 ++- .../struct_validate/meta/meta_name_value.rs | 5 +++- .../struct_validate/meta/meta_path.rs | 3 ++- 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/serde_valid_derive/src/attribute/field_validate.rs b/serde_valid_derive/src/attribute/field_validate.rs index 33a9403..c5296fc 100644 --- a/serde_valid_derive/src/attribute/field_validate.rs +++ b/serde_valid_derive/src/attribute/field_validate.rs @@ -8,9 +8,10 @@ mod object; mod string; pub use common::{ - MetaListCustomMessage, MetaListFieldValidation, MetaListStructValidation, - MetaNameValueCustomMessage, MetaNameValueFieldValidation, MetaNameValueStructValidation, - MetaPathCustomMessage, MetaPathFieldValidation, MetaPathStructValidation, + extract_custom_message_tokens, CustomMessageToken, MetaListCustomMessage, + MetaListFieldValidation, MetaListStructValidation, MetaNameValueCustomMessage, + MetaNameValueFieldValidation, MetaNameValueStructValidation, MetaPathCustomMessage, + MetaPathFieldValidation, MetaPathStructValidation, }; pub use field::{FieldValidators, Validator}; diff --git a/serde_valid_derive/src/attribute/struct_validate/meta.rs b/serde_valid_derive/src/attribute/struct_validate/meta.rs index 6d281e3..290efd1 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta.rs @@ -2,6 +2,7 @@ mod meta_list; mod meta_name_value; mod meta_path; +use crate::attribute::field_validate::{extract_custom_message_tokens, CustomMessageToken}; use crate::attribute::field_validate::{ MetaListStructValidation, MetaNameValueStructValidation, MetaPathStructValidation, Validator, }; @@ -40,15 +41,23 @@ fn inner_extract_struct_validator( )] })?; - match nested.len() { - 0 => Err(vec![crate::Error::struct_validation_type_required( + let custom_message = match nested.len() { + 0 => Err(vec![crate::Error::field_validation_type_required( attribute, )])?, - 1 => {} + 1 => CustomMessageToken::default(), + 2 => match extract_custom_message_tokens(&nested[1]) { + Ok(custom_message) => custom_message, + Err(message_fn_errors) => { + errors.extend(message_fn_errors); + CustomMessageToken::default() + } + }, _ => { for meta in nested.iter().skip(2) { errors.push(crate::Error::too_many_list_items(meta)); } + CustomMessageToken::default() } }; @@ -67,15 +76,19 @@ fn inner_extract_struct_validator( meta, ) { (Ok(validation_type), _, _, syn::Meta::Path(validation)) => { - extract_struct_validator_from_meta_path(validation_type, validation) + extract_struct_validator_from_meta_path(validation_type, validation, custom_message) } (_, Ok(validation_type), _, syn::Meta::List(validation)) => { - extract_struct_validator_from_meta_list(validation_type, validation) + extract_struct_validator_from_meta_list(validation_type, validation, custom_message) } (_, _, Ok(validation_type), syn::Meta::NameValue(validation)) => { - extract_struct_validator_from_meta_name_value(validation_type, validation) + extract_struct_validator_from_meta_name_value( + validation_type, + validation, + custom_message, + ) } (Ok(_), _, _, _) => Err(vec![crate::Error::meta_path_validation_need_value( diff --git a/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs b/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs index 7d587bd..484e3b6 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs @@ -1,9 +1,10 @@ -use crate::attribute::field_validate::{MetaListStructValidation, Validator}; +use crate::attribute::field_validate::{CustomMessageToken, MetaListStructValidation, Validator}; use crate::attribute::struct_validate::generic::extract_generic_struct_custom_validator; pub fn extract_struct_validator_from_meta_list( validation_type: MetaListStructValidation, validation: &syn::MetaList, + _custom_message: CustomMessageToken, ) -> Result { match validation_type { MetaListStructValidation::Custom => extract_generic_struct_custom_validator(validation), diff --git a/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs b/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs index b62e2d5..23926d0 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs @@ -1,9 +1,12 @@ -use crate::attribute::field_validate::{MetaNameValueStructValidation, Validator}; +use crate::attribute::field_validate::{ + CustomMessageToken, MetaNameValueStructValidation, Validator, +}; #[inline] pub fn extract_struct_validator_from_meta_name_value( validation_type: MetaNameValueStructValidation, _validation: &syn::MetaNameValue, + _custom_message: CustomMessageToken, ) -> Result { match validation_type {} } diff --git a/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs b/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs index 55d7d8f..2deba93 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs @@ -1,9 +1,10 @@ -use crate::attribute::field_validate::{MetaPathStructValidation, Validator}; +use crate::attribute::field_validate::{CustomMessageToken, MetaPathStructValidation, Validator}; #[inline] pub fn extract_struct_validator_from_meta_path( validation_type: MetaPathStructValidation, _validation: &syn::Path, + _custom_message: CustomMessageToken, ) -> Result { match validation_type {} } From 77d1a369d3a2a8eaf762c332b5f50d80ffae6abf Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Thu, 11 Jan 2024 00:26:11 +0900 Subject: [PATCH 02/25] refactor: warning. --- serde_valid/src/error.rs | 24 +++++++++---------- .../src/attribute/struct_validate/meta.rs | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/serde_valid/src/error.rs b/serde_valid/src/error.rs index 01665a4..cb12769 100644 --- a/serde_valid/src/error.rs +++ b/serde_valid/src/error.rs @@ -62,12 +62,23 @@ macro_rules! struct_error_params { pub $limit: Vec<$type>, } + impl $Error { + pub fn new($limit: &[T]) -> Self + where + T: Into<$type> + std::fmt::Debug + Clone, + { + Self { + $limit: (*$limit).iter().map(|x| x.clone().into()).collect(), + } + } + } + impl ToDefaultMessage for $Error { #[inline] fn to_default_message(&self) -> String { format!( $default_message, - self.enumerate.iter().map(|v| format!("{}", v)).join(", ") + self.$limit.iter().map(|v| format!("{}", v)).join(", ") ) } } @@ -233,14 +244,3 @@ struct_error_params!( pub enumerate: Vec, } ); - -impl EnumerateError { - pub fn new(enumerate: &[T]) -> Self - where - T: Into + std::fmt::Debug + Clone, - { - Self { - enumerate: (*enumerate).iter().map(|x| x.clone().into()).collect(), - } - } -} diff --git a/serde_valid_derive/src/attribute/struct_validate/meta.rs b/serde_valid_derive/src/attribute/struct_validate/meta.rs index 290efd1..5c370ca 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta.rs @@ -42,7 +42,7 @@ fn inner_extract_struct_validator( })?; let custom_message = match nested.len() { - 0 => Err(vec![crate::Error::field_validation_type_required( + 0 => Err(vec![crate::Error::struct_validation_type_required( attribute, )])?, 1 => CustomMessageToken::default(), From 266a09b1a8dcd36bfc21807a3bcee601366aff23 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Thu, 11 Jan 2024 01:19:41 +0900 Subject: [PATCH 03/25] wip: use custom_method. --- .../src/attribute/field_validate/generic/custom.rs | 3 ++- .../src/attribute/field_validate/meta/meta_list.rs | 2 +- .../src/attribute/struct_validate/generic/custom.rs | 11 ++++++----- .../src/attribute/struct_validate/meta/meta_list.rs | 6 ++++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/serde_valid_derive/src/attribute/field_validate/generic/custom.rs b/serde_valid_derive/src/attribute/field_validate/generic/custom.rs index 3ee9ec1..033d05c 100644 --- a/serde_valid_derive/src/attribute/field_validate/generic/custom.rs +++ b/serde_valid_derive/src/attribute/field_validate/generic/custom.rs @@ -1,4 +1,4 @@ -use crate::attribute::field_validate::Validator; +use crate::attribute::field_validate::{CustomMessageToken, Validator}; use crate::serde::rename::RenameMap; use crate::types::{CommaSeparatedNestedMetas, Field, SingleIdentPath}; use proc_macro2::TokenStream; @@ -7,6 +7,7 @@ use quote::quote; pub fn extract_generic_custom_validator( field: &impl Field, meta_list: &syn::MetaList, + _custom_message: CustomMessageToken, rename_map: &RenameMap, ) -> Result { let path = &meta_list.path; diff --git a/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs b/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs index 61888a3..6218b8a 100644 --- a/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs +++ b/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs @@ -18,7 +18,7 @@ pub fn extract_field_validator_from_meta_list( extract_generic_enumerate_validator(field, validation, custom_message, rename_map) } MetaListFieldValidation::Custom => { - extract_generic_custom_validator(field, validation, rename_map) + extract_generic_custom_validator(field, validation, custom_message, rename_map) } } } diff --git a/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs b/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs index 8517547..c554b1d 100644 --- a/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs +++ b/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs @@ -1,20 +1,21 @@ use quote::quote; -use crate::attribute::field_validate::Validator; +use crate::attribute::field_validate::{CustomMessageToken, Validator}; use crate::types::CommaSeparatedNestedMetas; pub fn extract_generic_struct_custom_validator( - meta_path: &syn::MetaList, + meta_list: &syn::MetaList, + _custom_message: CustomMessageToken, ) -> Result { let mut errors = vec![]; - let nested = meta_path + let nested = meta_list .parse_args_with(CommaSeparatedNestedMetas::parse_terminated) - .map_err(|error| vec![crate::Error::rule_args_parse_error(meta_path, &error)])?; + .map_err(|error| vec![crate::Error::rule_args_parse_error(meta_list, &error)])?; match nested.len() { 0 => Err(vec![ - crate::Error::validate_custom_need_function_or_closure(meta_path), + crate::Error::validate_custom_need_function_or_closure(meta_list), ])?, 2.. => nested .iter() diff --git a/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs b/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs index 484e3b6..fb6b441 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs @@ -4,9 +4,11 @@ use crate::attribute::struct_validate::generic::extract_generic_struct_custom_va pub fn extract_struct_validator_from_meta_list( validation_type: MetaListStructValidation, validation: &syn::MetaList, - _custom_message: CustomMessageToken, + custom_message: CustomMessageToken, ) -> Result { match validation_type { - MetaListStructValidation::Custom => extract_generic_struct_custom_validator(validation), + MetaListStructValidation::Custom => { + extract_generic_struct_custom_validator(validation, custom_message) + } } } From ba940f371098fd36d11925fd36c8f81bddd453e3 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Thu, 11 Jan 2024 01:25:00 +0900 Subject: [PATCH 04/25] refactor: change macro. --- serde_valid/src/validation.rs | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/serde_valid/src/validation.rs b/serde_valid/src/validation.rs index ed0771b..432fd78 100644 --- a/serde_valid/src/validation.rs +++ b/serde_valid/src/validation.rs @@ -132,8 +132,11 @@ macro_rules! impl_composited_validation_1args { &self, $limit:ident: $limit_type:ty$(,)* ) -> Result<(), Composited<$Error:ty>>; - }, - "safe_for_hashmap" + } + + impl $ValidateCompositedTrait2:ident for std::collections::HashMap + where + V: $ValidateCompositedTrait3:ident; ) => { impl_composited_validation_1args!( pub trait $ValidateCompositedTrait { @@ -144,9 +147,9 @@ macro_rules! impl_composited_validation_1args { } ); paste::paste! { - impl $ValidateCompositedTrait for std::collections::HashMap + impl $ValidateCompositedTrait2 for std::collections::HashMap where - V: $ValidateCompositedTrait, + V: $ValidateCompositedTrait3, { fn $validate_composited_method( &self, @@ -357,8 +360,11 @@ impl_composited_validation_1args!( &self, max_length: usize, ) -> Result<(), Composited>; - }, - "safe_for_hashmap" + } + + impl ValidateCompositedMaxLength for std::collections::HashMap + where + V: ValidateCompositedMaxLength; ); impl_composited_validation_1args!( @@ -367,8 +373,11 @@ impl_composited_validation_1args!( &self, min_length: usize, ) -> Result<(), Composited>; - }, - "safe_for_hashmap" + } + + impl ValidateCompositedMinLength for std::collections::HashMap + where + V: ValidateCompositedMinLength; ); impl_composited_validation_1args!( @@ -377,8 +386,11 @@ impl_composited_validation_1args!( &self, pattern: ®ex::Regex, ) -> Result<(), Composited>; - }, - "safe_for_hashmap" + } + + impl ValidateCompositedPattern for std::collections::HashMap + where + V: ValidateCompositedPattern; ); // Object From 9ebdf03867fdeaf053bc9ee822690a19551fd7fb Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Thu, 11 Jan 2024 10:37:59 +0900 Subject: [PATCH 05/25] docs: add docs. --- serde_valid/src/validation/error/composited.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/serde_valid/src/validation/error/composited.rs b/serde_valid/src/validation/error/composited.rs index 6700c09..b866e80 100644 --- a/serde_valid/src/validation/error/composited.rs +++ b/serde_valid/src/validation/error/composited.rs @@ -7,6 +7,18 @@ use crate::error::{ }; use indexmap::IndexMap; +/// Composited use Vec or Map error. +/// +/// Composited elevates field validation errors to per-element error in the array. +/// +/// # Examples +/// ```rust +/// pub struct Data { +/// #[validate(minimum = 0)] +/// #[validate(maximum = 10)] +/// pub val: Vec, // <-- Here +/// } +/// ``` #[derive(Debug)] pub enum Composited { Single(Error), From c47d60b976e207bee6a5b16b5c739ebf94781c86 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Thu, 11 Jan 2024 10:39:10 +0900 Subject: [PATCH 06/25] feat: add Default to CustomMessage. --- serde_valid/src/validation/error/custom_message.rs | 13 +++++++++++++ .../field_validate/common/custom_message.rs | 8 ++++++-- .../attribute/field_validate/generic/enumerate.rs | 2 +- .../attribute/field_validate/numeric/multiple_of.rs | 2 +- .../src/attribute/field_validate/numeric/range.rs | 2 +- .../field_validate/object/size_properties.rs | 2 +- .../src/attribute/field_validate/string/length.rs | 2 +- .../src/attribute/field_validate/string/pattern.rs | 2 +- 8 files changed, 25 insertions(+), 8 deletions(-) diff --git a/serde_valid/src/validation/error/custom_message.rs b/serde_valid/src/validation/error/custom_message.rs index 937abe6..4770165 100644 --- a/serde_valid/src/validation/error/custom_message.rs +++ b/serde_valid/src/validation/error/custom_message.rs @@ -18,3 +18,16 @@ impl CustomMessage { crate::validation::Message::new(error, self.message_fn) } } + +impl Default for CustomMessage +where + E: crate::validation::ToDefaultMessage, +{ + fn default() -> Self { + Self { + message_fn: crate::validation::ToDefaultMessage::to_default_message, + #[cfg(feature = "fluent")] + fluent_message: None, + } + } +} diff --git a/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs b/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs index 8f60b3c..b9a83dd 100644 --- a/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs +++ b/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs @@ -30,6 +30,10 @@ impl CustomMessageToken { } pub fn into_token(self) -> TokenStream { + if self.message_fn.is_none() && self.fluent_message.is_none() { + return quote!(None); + } + let message_fn = self.message_fn.unwrap_or(quote!( ::serde_valid::validation::ToDefaultMessage::to_default_message )); @@ -40,10 +44,10 @@ impl CustomMessageToken { let fluent_message = quote!(); quote!( - ::serde_valid::validation::CustomMessage{ + Some(::serde_valid::validation::CustomMessage{ message_fn: #message_fn, #fluent_message - } + }) ) } } diff --git a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs index ad91319..d371f8b 100644 --- a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs +++ b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs @@ -39,7 +39,7 @@ fn inner_extract_generic_enumerate_validator( #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message)); + .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); } )) } diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs index 56569c0..231c966 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs @@ -38,7 +38,7 @@ fn inner_extract_numeric_multiple_of_validator( #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message)); + .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); } )) } diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs index 628ea83..044a4ae 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs @@ -44,7 +44,7 @@ macro_rules! extract_numeric_range_validator{ #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message)); + .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); } )) } diff --git a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs index faa2590..df8fb5a 100644 --- a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs +++ b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs @@ -44,7 +44,7 @@ macro_rules! extract_object_size_validator { #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message)); + .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); } )) } diff --git a/serde_valid_derive/src/attribute/field_validate/string/length.rs b/serde_valid_derive/src/attribute/field_validate/string/length.rs index e9715bd..68902d4 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/length.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/length.rs @@ -44,7 +44,7 @@ macro_rules! extract_string_length_validator{ #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message)); + .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); } )) } diff --git a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs index 00a0a51..a8b72a1 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs @@ -46,7 +46,7 @@ fn inner_extract_string_pattern_validator( #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message)); + .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); } )) } From 6a6898e3eac962ec0e0104972e4141593709c32b Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Thu, 11 Jan 2024 10:48:54 +0900 Subject: [PATCH 07/25] fix: test. --- serde_valid/src/validation/error/composited.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/serde_valid/src/validation/error/composited.rs b/serde_valid/src/validation/error/composited.rs index b866e80..bce09d1 100644 --- a/serde_valid/src/validation/error/composited.rs +++ b/serde_valid/src/validation/error/composited.rs @@ -13,6 +13,9 @@ use indexmap::IndexMap; /// /// # Examples /// ```rust +/// use serde_valid::Validate; +/// +/// #[derive(Validate)] /// pub struct Data { /// #[validate(minimum = 0)] /// #[validate(maximum = 10)] From 20be4e07e075ac6fafe4a498af37cec14f937941 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Thu, 11 Jan 2024 10:49:01 +0900 Subject: [PATCH 08/25] fix: test. --- .../field_validate/common/custom_message.rs | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs b/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs index b9a83dd..809946c 100644 --- a/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs +++ b/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs @@ -29,6 +29,19 @@ impl CustomMessageToken { } } + #[cfg(not(feature = "fluent"))] + pub fn into_token(self) -> TokenStream { + match self.message_fn { + Some(message_fn) => quote!( + Some(::serde_valid::validation::CustomMessage{ + message_fn: #message_fn, + }) + ), + None => quote!(None), + } + } + + #[cfg(feature = "fluent")] pub fn into_token(self) -> TokenStream { if self.message_fn.is_none() && self.fluent_message.is_none() { return quote!(None); @@ -38,15 +51,10 @@ impl CustomMessageToken { ::serde_valid::validation::ToDefaultMessage::to_default_message )); - #[cfg(feature = "fluent")] - let fluent_message = quote!(fluent_message: None,); - #[cfg(not(feature = "fluent"))] - let fluent_message = quote!(); - quote!( Some(::serde_valid::validation::CustomMessage{ message_fn: #message_fn, - #fluent_message + fluent_message: None, }) ) } From a74ee64f07f51b1f7ce40eabf9b043a2493c6f59 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Thu, 11 Jan 2024 21:41:46 +0900 Subject: [PATCH 09/25] refactor: rename ToDefaultMessage to DefaultFormat. --- serde_valid/src/error.rs | 54 +++++++++---------- .../src/features/flatten/flat_errors.rs | 4 +- serde_valid/src/features/flatten/into_flat.rs | 20 +++---- .../src/features/fluent/into_localization.rs | 2 +- serde_valid/src/features/fluent/message.rs | 6 +-- serde_valid/src/validation.rs | 5 +- serde_valid/src/validation/error.rs | 4 +- .../src/validation/error/custom_message.rs | 4 +- serde_valid/src/validation/error/format.rs | 9 ++++ .../src/validation/error/into_error.rs | 6 +-- .../validation/error/to_default_message.rs | 9 ---- .../field_validate/array/length_items.rs | 4 +- .../field_validate/array/unique_items.rs | 4 +- .../field_validate/common/custom_message.rs | 2 +- .../field_validate/generic/enumerate.rs | 2 +- .../field_validate/numeric/multiple_of.rs | 2 +- .../attribute/field_validate/numeric/range.rs | 2 +- .../field_validate/object/size_properties.rs | 2 +- .../attribute/field_validate/string/length.rs | 2 +- .../field_validate/string/pattern.rs | 2 +- 20 files changed, 72 insertions(+), 73 deletions(-) create mode 100644 serde_valid/src/validation/error/format.rs delete mode 100644 serde_valid/src/validation/error/to_default_message.rs diff --git a/serde_valid/src/error.rs b/serde_valid/src/error.rs index cb12769..2bbdf18 100644 --- a/serde_valid/src/error.rs +++ b/serde_valid/src/error.rs @@ -1,8 +1,8 @@ use itertools::Itertools; use serde_valid_literal::Literal; +use crate::validation::DefaultFormat; use crate::validation::Number; -use crate::validation::ToDefaultMessage; #[derive(Debug, thiserror::Error)] pub enum Error @@ -52,7 +52,7 @@ where macro_rules! struct_error_params { ( #[derive(Debug, Clone)] - #[default_message=$default_message:literal] + #[default_format=$default_format:literal] pub struct $Error:ident { pub $limit:ident: Vec<$type:ty>, } @@ -73,11 +73,11 @@ macro_rules! struct_error_params { } } - impl ToDefaultMessage for $Error { + impl DefaultFormat for $Error { #[inline] - fn to_default_message(&self) -> String { + fn default_format(&self) -> String { format!( - $default_message, + $default_format, self.$limit.iter().map(|v| format!("{}", v)).join(", ") ) } @@ -86,7 +86,7 @@ macro_rules! struct_error_params { ( #[derive(Debug, Clone)] - #[default_message=$default_message:literal] + #[default_format=$default_format:literal] pub struct $Error:ident { pub $limit:ident: $type:ty, } @@ -104,27 +104,27 @@ macro_rules! struct_error_params { } } - impl ToDefaultMessage for $Error { + impl DefaultFormat for $Error { #[inline] - fn to_default_message(&self) -> String { - format!($default_message, self.$limit) + fn default_format(&self) -> String { + format!($default_format, self.$limit) } } }; ( #[derive(Debug, Clone)] - #[default_message=$default_message:literal] + #[default_format=$default_format:literal] pub struct $Error:ident { } ) => { #[derive(Debug, Clone)] pub struct $Error {} - impl ToDefaultMessage for $Error { + impl DefaultFormat for $Error { #[inline] - fn to_default_message(&self) -> String { - format!($default_message) + fn default_format(&self) -> String { + format!($default_format) } } }; @@ -133,7 +133,7 @@ macro_rules! struct_error_params { // Number struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The number must be `>= {}`."] + #[default_format = "The number must be `>= {}`."] pub struct MinimumError { pub minimum: Number, } @@ -141,7 +141,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The number must be `<= {}`."] + #[default_format = "The number must be `<= {}`."] pub struct MaximumError { pub maximum: Number, } @@ -149,7 +149,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The number must be `> {}`."] + #[default_format = "The number must be `> {}`."] pub struct ExclusiveMinimumError { pub exclusive_minimum: Number, } @@ -157,7 +157,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The number must be `< {}`."] + #[default_format = "The number must be `< {}`."] pub struct ExclusiveMaximumError { pub exclusive_maximum: Number, } @@ -165,7 +165,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The value must be multiple of `{}`."] + #[default_format = "The value must be multiple of `{}`."] pub struct MultipleOfError { pub multiple_of: Number, } @@ -174,7 +174,7 @@ struct_error_params!( // String struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The length of the value must be `>= {}`."] + #[default_format = "The length of the value must be `>= {}`."] pub struct MinLengthError { pub min_length: usize, } @@ -182,7 +182,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The length of the value must be `<= {}`."] + #[default_format = "The length of the value must be `<= {}`."] pub struct MaxLengthError { pub max_length: usize, } @@ -190,7 +190,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The value must match the pattern of \"{0}\"."] + #[default_format = "The value must match the pattern of \"{0}\"."] pub struct PatternError { pub pattern: String, } @@ -199,7 +199,7 @@ struct_error_params!( // Array struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The length of the items must be `<= {}`."] + #[default_format = "The length of the items must be `<= {}`."] pub struct MaxItemsError { pub max_items: usize, } @@ -207,7 +207,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The length of the items must be `>= {}`."] + #[default_format = "The length of the items must be `>= {}`."] pub struct MinItemsError { pub min_items: usize, } @@ -215,14 +215,14 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The items must be unique."] + #[default_format = "The items must be unique."] pub struct UniqueItemsError {} ); // Object struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The size of the properties must be `<= {}`."] + #[default_format = "The size of the properties must be `<= {}`."] pub struct MaxPropertiesError { pub max_properties: usize, } @@ -230,7 +230,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The size of the properties must be `>= {}`."] + #[default_format = "The size of the properties must be `>= {}`."] pub struct MinPropertiesError { pub min_properties: usize, } @@ -239,7 +239,7 @@ struct_error_params!( // Generic struct_error_params!( #[derive(Debug, Clone)] - #[default_message = "The value must be in [{:}]."] + #[default_format = "The value must be in [{:}]."] pub struct EnumerateError { pub enumerate: Vec, } diff --git a/serde_valid/src/features/flatten/flat_errors.rs b/serde_valid/src/features/flatten/flat_errors.rs index 6eda796..6024757 100644 --- a/serde_valid/src/features/flatten/flat_errors.rs +++ b/serde_valid/src/features/flatten/flat_errors.rs @@ -51,7 +51,7 @@ mod tests { use crate::{ flatten::IntoFlat, - validation::{ArrayErrors, Error, Errors, Message, ToDefaultMessage}, + validation::{ArrayErrors, DefaultFormat, Error, Errors, Message}, MinItemsError, }; @@ -62,7 +62,7 @@ mod tests { Errors::Array(ArrayErrors { errors: vec![Error::MinItems(Message::new( MinItemsError { min_items: 1 }, - MinItemsError::to_default_message + MinItemsError::default_format ))], items: indexmap! {}, }) diff --git a/serde_valid/src/features/flatten/into_flat.rs b/serde_valid/src/features/flatten/into_flat.rs index 46fe096..1c532e4 100644 --- a/serde_valid/src/features/flatten/into_flat.rs +++ b/serde_valid/src/features/flatten/into_flat.rs @@ -1,7 +1,7 @@ use jsonschema::paths::{JSONPointer, PathChunk}; use crate::validation::{ - ArrayErrors, ItemErrorsMap, Message, ObjectErrors, PropertyErrorsMap, ToDefaultMessage, + ArrayErrors, DefaultFormat, ItemErrorsMap, Message, ObjectErrors, PropertyErrorsMap, }; use super::{FlatError, FlatErrors}; @@ -109,7 +109,7 @@ where impl IntoFlat for Message where - T: ToDefaultMessage, + T: DefaultFormat, { fn into_flat_at(self, path: &JSONPointer) -> FlatErrors { FlatErrors::new(vec![FlatError::new(path.to_owned(), self.error())]) @@ -168,13 +168,13 @@ mod tests { fn array_errors_flatten() { let min_items = Message::new( MinItemsError { min_items: 1 }, - MinItemsError::to_default_message, + MinItemsError::default_format, ); let maximum = Message::new( MaximumError { maximum: Number::I32(1), }, - MaximumError::to_default_message, + MaximumError::default_format, ); assert_eq!( Errors::Array(ArrayErrors { @@ -203,29 +203,29 @@ mod tests { FlatErrors::new(vec![ FlatError::new( JSONPointer::default(), - min_items.error().to_default_message(), + min_items.error().default_format(), ), FlatError::new( JSONPointer::from([PathChunk::from(0)].as_ref()), - maximum.error().to_default_message(), + maximum.error().default_format(), ), FlatError::new( JSONPointer::from([PathChunk::from(0), PathChunk::from(2)].as_ref()), - maximum.error().to_default_message(), + maximum.error().default_format(), ), FlatError::new( JSONPointer::from([PathChunk::from(3)].as_ref()), - maximum.error().to_default_message(), + maximum.error().default_format(), ), FlatError::new( JSONPointer::from([PathChunk::from(5)].as_ref()), - maximum.error().to_default_message(), + maximum.error().default_format(), ), FlatError::new( JSONPointer::from( [PathChunk::from(5), PathChunk::from("name".to_owned())].as_ref() ), - maximum.error().to_default_message(), + maximum.error().default_format(), ) ]) ); diff --git a/serde_valid/src/features/fluent/into_localization.rs b/serde_valid/src/features/fluent/into_localization.rs index 8b7db32..036b908 100644 --- a/serde_valid/src/features/fluent/into_localization.rs +++ b/serde_valid/src/features/fluent/into_localization.rs @@ -193,7 +193,7 @@ mod test { let error = crate::validation::Error::Maximum( CustomMessage { - message_fn: crate::validation::ToDefaultMessage::to_default_message, + message_fn: crate::validation::DefaultFormat::default_format, fluent_message: Some(Message { id: "intro", args: vec![("name", FluentValue::from("John"))], diff --git a/serde_valid/src/features/fluent/message.rs b/serde_valid/src/features/fluent/message.rs index e04b1b8..5c9616f 100644 --- a/serde_valid/src/features/fluent/message.rs +++ b/serde_valid/src/features/fluent/message.rs @@ -1,6 +1,6 @@ use fluent_0::FluentValue; -use crate::validation::ToDefaultMessage; +use crate::validation::DefaultFormat; #[derive(Debug, Clone)] pub struct Message { @@ -14,9 +14,9 @@ impl std::fmt::Display for Message { } } -impl ToDefaultMessage for Message { +impl DefaultFormat for Message { #[inline] - fn to_default_message(&self) -> String { + fn default_format(&self) -> String { self.id.to_string() } } diff --git a/serde_valid/src/validation.rs b/serde_valid/src/validation.rs index 432fd78..ed7f09b 100644 --- a/serde_valid/src/validation.rs +++ b/serde_valid/src/validation.rs @@ -12,9 +12,8 @@ use crate::{ }; pub use array::{ValidateMaxItems, ValidateMinItems, ValidateUniqueItems}; pub use error::{ - ArrayErrors, Composited, CustomMessage, Error, Errors, IntoError, ItemErrorsMap, - ItemVecErrorsMap, Message, ObjectErrors, PropertyErrorsMap, PropertyVecErrorsMap, - ToDefaultMessage, VecErrors, + ArrayErrors, Composited, CustomMessage, DefaultFormat, Error, Errors, IntoError, ItemErrorsMap, + ItemVecErrorsMap, Message, ObjectErrors, PropertyErrorsMap, PropertyVecErrorsMap, VecErrors, }; pub use generic::ValidateEnumerate; use indexmap::IndexMap; diff --git a/serde_valid/src/validation/error.rs b/serde_valid/src/validation/error.rs index 7cf8f8f..48f0247 100644 --- a/serde_valid/src/validation/error.rs +++ b/serde_valid/src/validation/error.rs @@ -2,10 +2,10 @@ mod array_erros; mod composited; mod custom_message; mod errors; +mod format; mod into_error; mod message; mod object_errors; -mod to_default_message; pub use crate::error::{ EnumerateError, ExclusiveMaximumError, ExclusiveMinimumError, MaxItemsError, MaxLengthError, @@ -16,11 +16,11 @@ pub use array_erros::ArrayErrors; pub use composited::Composited; pub use custom_message::CustomMessage; pub use errors::Errors; +pub use format::DefaultFormat; use indexmap::IndexMap; pub use into_error::IntoError; pub use message::Message; pub use object_errors::ObjectErrors; -pub use to_default_message::ToDefaultMessage; #[derive(Debug, Clone, serde::Serialize, thiserror::Error)] #[serde(untagged)] diff --git a/serde_valid/src/validation/error/custom_message.rs b/serde_valid/src/validation/error/custom_message.rs index 4770165..ad6d3ef 100644 --- a/serde_valid/src/validation/error/custom_message.rs +++ b/serde_valid/src/validation/error/custom_message.rs @@ -21,11 +21,11 @@ impl CustomMessage { impl Default for CustomMessage where - E: crate::validation::ToDefaultMessage, + E: crate::validation::DefaultFormat, { fn default() -> Self { Self { - message_fn: crate::validation::ToDefaultMessage::to_default_message, + message_fn: crate::validation::DefaultFormat::default_format, #[cfg(feature = "fluent")] fluent_message: None, } diff --git a/serde_valid/src/validation/error/format.rs b/serde_valid/src/validation/error/format.rs new file mode 100644 index 0000000..7f93acb --- /dev/null +++ b/serde_valid/src/validation/error/format.rs @@ -0,0 +1,9 @@ +pub trait DefaultFormat { + fn default_format(&self) -> String; +} + +impl DefaultFormat for String { + fn default_format(&self) -> String { + self.into() + } +} diff --git a/serde_valid/src/validation/error/into_error.rs b/serde_valid/src/validation/error/into_error.rs index 2158eb0..9fd5f01 100644 --- a/serde_valid/src/validation/error/into_error.rs +++ b/serde_valid/src/validation/error/into_error.rs @@ -1,14 +1,14 @@ -use crate::validation::ToDefaultMessage; +use crate::validation::DefaultFormat; use super::CustomMessage; pub trait IntoError: Sized where - E: ToDefaultMessage, + E: DefaultFormat, { fn into_error(self) -> crate::validation::Error { self.into_error_by(CustomMessage { - message_fn: E::to_default_message, + message_fn: E::default_format, #[cfg(feature = "fluent")] fluent_message: None, }) diff --git a/serde_valid/src/validation/error/to_default_message.rs b/serde_valid/src/validation/error/to_default_message.rs deleted file mode 100644 index 98c7c70..0000000 --- a/serde_valid/src/validation/error/to_default_message.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub trait ToDefaultMessage { - fn to_default_message(&self) -> String; -} - -impl ToDefaultMessage for String { - fn to_default_message(&self) -> String { - self.into() - } -} diff --git a/serde_valid_derive/src/attribute/field_validate/array/length_items.rs b/serde_valid_derive/src/attribute/field_validate/array/length_items.rs index b47c32d..8998022 100644 --- a/serde_valid_derive/src/attribute/field_validate/array/length_items.rs +++ b/serde_valid_derive/src/attribute/field_validate/array/length_items.rs @@ -33,14 +33,14 @@ macro_rules! extract_array_length_validator{ let [<$ErrorType:snake>] = get_numeric(validation_value)?; let errors = field.errors_variable(); let message_fn = custom_message - .message_fn.unwrap_or(quote!(::serde_valid::[<$ErrorType Error>]::to_default_message)); + .message_fn.unwrap_or(quote!(::serde_valid::[<$ErrorType Error>]::default_format)); Ok(quote!( if let Err(error_params) = ::serde_valid::[]::[]( #field_ident, #[<$ErrorType:snake>], ) { - use ::serde_valid::validation::ToDefaultMessage; + use ::serde_valid::validation::DefaultFormat; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs b/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs index ae08717..5ab326e 100644 --- a/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs +++ b/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs @@ -24,13 +24,13 @@ fn inner_extract_array_unique_items_validator( let errors = field.errors_variable(); let message_fn = custom_message .message_fn - .unwrap_or(quote!(::serde_valid::UniqueItemsError::to_default_message)); + .unwrap_or(quote!(::serde_valid::UniqueItemsError::default_format)); quote!( if let Err(error_params) = ::serde_valid::ValidateUniqueItems::validate_unique_items( #field_ident ) { - use ::serde_valid::validation::ToDefaultMessage; + use ::serde_valid::validation::DefaultFormat; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs b/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs index 809946c..08fd925 100644 --- a/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs +++ b/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs @@ -48,7 +48,7 @@ impl CustomMessageToken { } let message_fn = self.message_fn.unwrap_or(quote!( - ::serde_valid::validation::ToDefaultMessage::to_default_message + ::serde_valid::validation::DefaultFormat::default_format )); quote!( diff --git a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs index d371f8b..41dff11 100644 --- a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs +++ b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs @@ -34,7 +34,7 @@ fn inner_extract_generic_enumerate_validator( #field_ident, &[#enumerate], ) { - use ::serde_valid::validation::{IntoError, ToDefaultMessage}; + use ::serde_valid::validation::{IntoError, DefaultFormat}; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs index 231c966..188cda9 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs @@ -33,7 +33,7 @@ fn inner_extract_numeric_multiple_of_validator( #field_ident, #multiple_of, ) { - use ::serde_valid::validation::{IntoError, ToDefaultMessage}; + use ::serde_valid::validation::{IntoError, DefaultFormat}; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs index 044a4ae..5f1db21 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs @@ -39,7 +39,7 @@ macro_rules! extract_numeric_range_validator{ #field_ident, #[<$ErrorType:snake>], ) { - use ::serde_valid::validation::{IntoError, ToDefaultMessage}; + use ::serde_valid::validation::{IntoError, DefaultFormat}; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs index df8fb5a..04f21eb 100644 --- a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs +++ b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs @@ -39,7 +39,7 @@ macro_rules! extract_object_size_validator { #field_ident, #[<$ErrorType:snake>] ) { - use ::serde_valid::validation::{IntoError, ToDefaultMessage}; + use ::serde_valid::validation::{IntoError, DefaultFormat}; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/string/length.rs b/serde_valid_derive/src/attribute/field_validate/string/length.rs index 68902d4..74ba868 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/length.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/length.rs @@ -39,7 +39,7 @@ macro_rules! extract_string_length_validator{ #field_ident, #[<$ErrorType:snake>], ) { - use ::serde_valid::validation::{IntoError, ToDefaultMessage}; + use ::serde_valid::validation::{IntoError, DefaultFormat}; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs index a8b72a1..e07cb5c 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs @@ -41,7 +41,7 @@ fn inner_extract_string_pattern_validator( #field_ident, __pattern, ) { - use ::serde_valid::validation::{IntoError, ToDefaultMessage}; + use ::serde_valid::validation::{IntoError, DefaultFormat}; #errors .entry(#rename) From e604baaabe8ac73262f8a9f91cbf42cf28b9b3ef Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Thu, 11 Jan 2024 22:01:32 +0900 Subject: [PATCH 10/25] refine: error module restructured. --- serde_valid/src/error.rs | 2 +- .../src/features/flatten/flat_errors.rs | 3 +- serde_valid/src/features/flatten/into_flat.rs | 2 +- .../src/features/fluent/into_localization.rs | 10 +++--- serde_valid/src/features/fluent/message.rs | 2 +- serde_valid/src/lib.rs | 6 ++-- serde_valid/src/validation.rs | 9 +++-- .../src/validation/{error => }/composited.rs | 10 +++--- serde_valid/src/validation/error.rs | 6 +--- .../src/validation/error/custom_message.rs | 33 ------------------ serde_valid/src/validation/error/format.rs | 34 +++++++++++++++++++ .../src/validation/error/into_error.rs | 8 ++--- .../field_validate/array/length_items.rs | 4 +-- .../field_validate/array/unique_items.rs | 4 +-- .../field_validate/common/custom_message.rs | 6 ++-- .../field_validate/generic/enumerate.rs | 3 +- .../field_validate/numeric/multiple_of.rs | 3 +- .../attribute/field_validate/numeric/range.rs | 3 +- .../field_validate/object/size_properties.rs | 3 +- .../attribute/field_validate/string/length.rs | 3 +- .../field_validate/string/pattern.rs | 3 +- serde_valid_derive/src/error.rs | 6 ++-- 22 files changed, 85 insertions(+), 78 deletions(-) rename serde_valid/src/validation/{error => }/composited.rs (84%) delete mode 100644 serde_valid/src/validation/error/custom_message.rs diff --git a/serde_valid/src/error.rs b/serde_valid/src/error.rs index 2bbdf18..7b74154 100644 --- a/serde_valid/src/error.rs +++ b/serde_valid/src/error.rs @@ -1,7 +1,7 @@ use itertools::Itertools; use serde_valid_literal::Literal; -use crate::validation::DefaultFormat; +use crate::validation::error::DefaultFormat; use crate::validation::Number; #[derive(Debug, thiserror::Error)] diff --git a/serde_valid/src/features/flatten/flat_errors.rs b/serde_valid/src/features/flatten/flat_errors.rs index 6024757..4081fdd 100644 --- a/serde_valid/src/features/flatten/flat_errors.rs +++ b/serde_valid/src/features/flatten/flat_errors.rs @@ -51,7 +51,8 @@ mod tests { use crate::{ flatten::IntoFlat, - validation::{ArrayErrors, DefaultFormat, Error, Errors, Message}, + validation::error::{ArrayErrors, DefaultFormat, Message}, + validation::{Error, Errors}, MinItemsError, }; diff --git a/serde_valid/src/features/flatten/into_flat.rs b/serde_valid/src/features/flatten/into_flat.rs index 1c532e4..1963952 100644 --- a/serde_valid/src/features/flatten/into_flat.rs +++ b/serde_valid/src/features/flatten/into_flat.rs @@ -1,6 +1,6 @@ use jsonschema::paths::{JSONPointer, PathChunk}; -use crate::validation::{ +use crate::validation::error::{ ArrayErrors, DefaultFormat, ItemErrorsMap, Message, ObjectErrors, PropertyErrorsMap, }; diff --git a/serde_valid/src/features/fluent/into_localization.rs b/serde_valid/src/features/fluent/into_localization.rs index 036b908..45ac1bb 100644 --- a/serde_valid/src/features/fluent/into_localization.rs +++ b/serde_valid/src/features/fluent/into_localization.rs @@ -1,6 +1,6 @@ use fluent_0::{FluentArgs, FluentBundle, FluentResource}; -use crate::validation::{ +use crate::validation::error::{ ArrayErrors, Errors, ItemErrorsMap, ObjectErrors, PropertyErrorsMap, VecErrors, }; @@ -126,7 +126,7 @@ fn localize( } fn localize_or_default( - message: &crate::validation::Message, + message: &crate::validation::error::Message, bundle: &FluentBundle, ) -> String { if let Some(value) = localize(message.fluent_message.as_ref(), bundle) { @@ -138,7 +138,7 @@ fn localize_or_default( #[cfg(test)] mod test { - use crate::{fluent::Message, validation::CustomMessage}; + use crate::{fluent::Message, validation::error::Format}; use super::*; use fluent_0::{FluentResource, FluentValue}; @@ -192,8 +192,8 @@ mod test { bundle.add_resource(res).unwrap(); let error = crate::validation::Error::Maximum( - CustomMessage { - message_fn: crate::validation::DefaultFormat::default_format, + Format { + message_fn: crate::validation::error::DefaultFormat::default_format, fluent_message: Some(Message { id: "intro", args: vec![("name", FluentValue::from("John"))], diff --git a/serde_valid/src/features/fluent/message.rs b/serde_valid/src/features/fluent/message.rs index 5c9616f..2723aea 100644 --- a/serde_valid/src/features/fluent/message.rs +++ b/serde_valid/src/features/fluent/message.rs @@ -1,6 +1,6 @@ use fluent_0::FluentValue; -use crate::validation::DefaultFormat; +use crate::validation::error::DefaultFormat; #[derive(Debug, Clone)] pub struct Message { diff --git a/serde_valid/src/lib.rs b/serde_valid/src/lib.rs index 837cc95..95ada8e 100644 --- a/serde_valid/src/lib.rs +++ b/serde_valid/src/lib.rs @@ -594,7 +594,7 @@ where Ok(()) } else { Err(self::validation::Errors::Array( - validation::ArrayErrors::new(vec![], items), + validation::error::ArrayErrors::new(vec![], items), )) } } @@ -617,7 +617,7 @@ where Ok(()) } else { Err(self::validation::Errors::Array( - validation::ArrayErrors::new(vec![], items), + validation::error::ArrayErrors::new(vec![], items), )) } } @@ -641,7 +641,7 @@ where Ok(()) } else { Err(self::validation::Errors::Object( - validation::ObjectErrors::new(vec![], items), + validation::error::ObjectErrors::new(vec![], items), )) } } diff --git a/serde_valid/src/validation.rs b/serde_valid/src/validation.rs index ed7f09b..c0d6f04 100644 --- a/serde_valid/src/validation.rs +++ b/serde_valid/src/validation.rs @@ -1,5 +1,6 @@ mod array; -mod error; +mod composited; +pub mod error; mod generic; mod numeric; mod object; @@ -10,10 +11,12 @@ use crate::{ MaxPropertiesError, MaximumError, MinLengthError, MinPropertiesError, MinimumError, MultipleOfError, PatternError, }; +pub use composited::Composited; + pub use array::{ValidateMaxItems, ValidateMinItems, ValidateUniqueItems}; pub use error::{ - ArrayErrors, Composited, CustomMessage, DefaultFormat, Error, Errors, IntoError, ItemErrorsMap, - ItemVecErrorsMap, Message, ObjectErrors, PropertyErrorsMap, PropertyVecErrorsMap, VecErrors, + ArrayErrors, Error, Errors, IntoError, ItemErrorsMap, ItemVecErrorsMap, ObjectErrors, + PropertyErrorsMap, PropertyVecErrorsMap, VecErrors, }; pub use generic::ValidateEnumerate; use indexmap::IndexMap; diff --git a/serde_valid/src/validation/error/composited.rs b/serde_valid/src/validation/composited.rs similarity index 84% rename from serde_valid/src/validation/error/composited.rs rename to serde_valid/src/validation/composited.rs index bce09d1..a092705 100644 --- a/serde_valid/src/validation/error/composited.rs +++ b/serde_valid/src/validation/composited.rs @@ -1,5 +1,5 @@ -use super::into_error::IntoError; -use super::{custom_message::CustomMessage, Error}; +use crate::validation::error::IntoError; + use crate::error::{ EnumerateError, ExclusiveMaximumError, ExclusiveMinimumError, MaxItemsError, MaxLengthError, MaxPropertiesError, MaximumError, MinItemsError, MinLengthError, MinPropertiesError, @@ -32,13 +32,13 @@ macro_rules! impl_into_error { ($ErrorType:ident) => { paste::paste! { impl IntoError<[<$ErrorType Error>]> for Composited<[<$ErrorType Error>]> { - fn into_error_by(self, custom: CustomMessage<[<$ErrorType Error>]>) -> Error { + fn into_error_by(self, custom: crate::validation::error::Format<[<$ErrorType Error>]>) -> crate::validation::error::Error { match self { Composited::Single(single) => { - Error::$ErrorType(custom.into_message(single)) + crate::validation::error::Error::$ErrorType(custom.into_message(single)) }, Composited::Array(array) =>{ - Error::Items(crate::validation::ArrayErrors::new( + crate::validation::error::Error::Items(crate::validation::error::ArrayErrors::new( Vec::with_capacity(0), array .into_iter() diff --git a/serde_valid/src/validation/error.rs b/serde_valid/src/validation/error.rs index 48f0247..4a01197 100644 --- a/serde_valid/src/validation/error.rs +++ b/serde_valid/src/validation/error.rs @@ -1,6 +1,4 @@ mod array_erros; -mod composited; -mod custom_message; mod errors; mod format; mod into_error; @@ -13,10 +11,8 @@ pub use crate::error::{ MinimumError, MultipleOfError, PatternError, UniqueItemsError, }; pub use array_erros::ArrayErrors; -pub use composited::Composited; -pub use custom_message::CustomMessage; pub use errors::Errors; -pub use format::DefaultFormat; +pub use format::{DefaultFormat, Format}; use indexmap::IndexMap; pub use into_error::IntoError; pub use message::Message; diff --git a/serde_valid/src/validation/error/custom_message.rs b/serde_valid/src/validation/error/custom_message.rs deleted file mode 100644 index ad6d3ef..0000000 --- a/serde_valid/src/validation/error/custom_message.rs +++ /dev/null @@ -1,33 +0,0 @@ -#[derive(Clone)] -pub struct CustomMessage { - pub message_fn: fn(&E) -> String, - #[cfg(feature = "fluent")] - pub fluent_message: Option, -} - -impl CustomMessage { - #[cfg(feature = "fluent")] - pub fn into_message(self, error: E) -> crate::validation::Message { - let mut message = crate::validation::Message::new(error, self.message_fn); - message.fluent_message = self.fluent_message; - message - } - - #[cfg(not(feature = "fluent"))] - pub fn into_message(self, error: E) -> crate::validation::Message { - crate::validation::Message::new(error, self.message_fn) - } -} - -impl Default for CustomMessage -where - E: crate::validation::DefaultFormat, -{ - fn default() -> Self { - Self { - message_fn: crate::validation::DefaultFormat::default_format, - #[cfg(feature = "fluent")] - fluent_message: None, - } - } -} diff --git a/serde_valid/src/validation/error/format.rs b/serde_valid/src/validation/error/format.rs index 7f93acb..2fd954f 100644 --- a/serde_valid/src/validation/error/format.rs +++ b/serde_valid/src/validation/error/format.rs @@ -1,3 +1,37 @@ +#[derive(Clone)] +pub struct Format { + pub message_fn: fn(&E) -> String, + #[cfg(feature = "fluent")] + pub fluent_message: Option, +} + +impl Format { + #[cfg(feature = "fluent")] + pub fn into_message(self, error: E) -> crate::validation::error::Message { + let mut message = crate::validation::error::Message::new(error, self.message_fn); + message.fluent_message = self.fluent_message; + message + } + + #[cfg(not(feature = "fluent"))] + pub fn into_message(self, error: E) -> crate::validation::error::Message { + crate::validation::error::Message::new(error, self.message_fn) + } +} + +impl Default for Format +where + E: crate::validation::error::DefaultFormat, +{ + fn default() -> Self { + Self { + message_fn: crate::validation::error::DefaultFormat::default_format, + #[cfg(feature = "fluent")] + fluent_message: None, + } + } +} + pub trait DefaultFormat { fn default_format(&self) -> String; } diff --git a/serde_valid/src/validation/error/into_error.rs b/serde_valid/src/validation/error/into_error.rs index 9fd5f01..4a643c5 100644 --- a/serde_valid/src/validation/error/into_error.rs +++ b/serde_valid/src/validation/error/into_error.rs @@ -1,18 +1,18 @@ -use crate::validation::DefaultFormat; +use crate::validation::error::DefaultFormat; -use super::CustomMessage; +use super::Format; pub trait IntoError: Sized where E: DefaultFormat, { fn into_error(self) -> crate::validation::Error { - self.into_error_by(CustomMessage { + self.into_error_by(Format { message_fn: E::default_format, #[cfg(feature = "fluent")] fluent_message: None, }) } - fn into_error_by(self, custom: CustomMessage) -> crate::validation::Error; + fn into_error_by(self, custom: Format) -> crate::validation::Error; } diff --git a/serde_valid_derive/src/attribute/field_validate/array/length_items.rs b/serde_valid_derive/src/attribute/field_validate/array/length_items.rs index 8998022..cd2d532 100644 --- a/serde_valid_derive/src/attribute/field_validate/array/length_items.rs +++ b/serde_valid_derive/src/attribute/field_validate/array/length_items.rs @@ -40,13 +40,13 @@ macro_rules! extract_array_length_validator{ #field_ident, #[<$ErrorType:snake>], ) { - use ::serde_valid::validation::DefaultFormat; + use ::serde_valid::validation::error::DefaultFormat; #errors .entry(#rename) .or_default() .push(::serde_valid::validation::Error::$ErrorType( - ::serde_valid::validation::Message::new( + ::serde_valid::validation::error::Message::new( error_params, #message_fn, ) diff --git a/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs b/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs index 5ab326e..865e572 100644 --- a/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs +++ b/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs @@ -30,13 +30,13 @@ fn inner_extract_array_unique_items_validator( if let Err(error_params) = ::serde_valid::ValidateUniqueItems::validate_unique_items( #field_ident ) { - use ::serde_valid::validation::DefaultFormat; + use ::serde_valid::validation::error::DefaultFormat; #errors .entry(#rename) .or_default() .push(::serde_valid::validation::Error::UniqueItems( - ::serde_valid::validation::Message::new( + ::serde_valid::validation::error::Message::new( error_params, #message_fn, ) diff --git a/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs b/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs index 08fd925..9f03f41 100644 --- a/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs +++ b/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs @@ -33,7 +33,7 @@ impl CustomMessageToken { pub fn into_token(self) -> TokenStream { match self.message_fn { Some(message_fn) => quote!( - Some(::serde_valid::validation::CustomMessage{ + Some(::serde_valid::validation::error::Format{ message_fn: #message_fn, }) ), @@ -48,11 +48,11 @@ impl CustomMessageToken { } let message_fn = self.message_fn.unwrap_or(quote!( - ::serde_valid::validation::DefaultFormat::default_format + ::serde_valid::validation::error::DefaultFormat::default_format )); quote!( - Some(::serde_valid::validation::CustomMessage{ + Some(::serde_valid::validation::error::Format{ message_fn: #message_fn, fluent_message: None, }) diff --git a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs index 41dff11..08e14eb 100644 --- a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs +++ b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs @@ -34,7 +34,8 @@ fn inner_extract_generic_enumerate_validator( #field_ident, &[#enumerate], ) { - use ::serde_valid::validation::{IntoError, DefaultFormat}; + use ::serde_valid::validation::IntoError; + use ::serde_valid::validation::error::DefaultFormat; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs index 188cda9..853c7b8 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs @@ -33,7 +33,8 @@ fn inner_extract_numeric_multiple_of_validator( #field_ident, #multiple_of, ) { - use ::serde_valid::validation::{IntoError, DefaultFormat}; + use ::serde_valid::validation::IntoError; + use ::serde_valid::validation::error::DefaultFormat; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs index 5f1db21..cb96081 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs @@ -39,7 +39,8 @@ macro_rules! extract_numeric_range_validator{ #field_ident, #[<$ErrorType:snake>], ) { - use ::serde_valid::validation::{IntoError, DefaultFormat}; + use ::serde_valid::validation::IntoError; + use ::serde_valid::validation::error::DefaultFormat; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs index 04f21eb..d9a16a3 100644 --- a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs +++ b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs @@ -39,7 +39,8 @@ macro_rules! extract_object_size_validator { #field_ident, #[<$ErrorType:snake>] ) { - use ::serde_valid::validation::{IntoError, DefaultFormat}; + use ::serde_valid::validation::IntoError; + use ::serde_valid::validation::error::DefaultFormat; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/string/length.rs b/serde_valid_derive/src/attribute/field_validate/string/length.rs index 74ba868..c9cfb05 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/length.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/length.rs @@ -39,7 +39,8 @@ macro_rules! extract_string_length_validator{ #field_ident, #[<$ErrorType:snake>], ) { - use ::serde_valid::validation::{IntoError, DefaultFormat}; + use ::serde_valid::validation::IntoError; + use ::serde_valid::validation::error::DefaultFormat; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs index e07cb5c..07c36c9 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs @@ -41,7 +41,8 @@ fn inner_extract_string_pattern_validator( #field_ident, __pattern, ) { - use ::serde_valid::validation::{IntoError, DefaultFormat}; + use ::serde_valid::validation::IntoError; + use ::serde_valid::validation::error::DefaultFormat; #errors .entry(#rename) diff --git a/serde_valid_derive/src/error.rs b/serde_valid_derive/src/error.rs index 8e3e0e6..85922b1 100644 --- a/serde_valid_derive/src/error.rs +++ b/serde_valid_derive/src/error.rs @@ -55,7 +55,7 @@ pub fn object_errors_tokens() -> TokenStream { ( field, ::serde_valid::validation::Errors::Array( - ::serde_valid::validation::ArrayErrors::new( + ::serde_valid::validation::error::ArrayErrors::new( __field_errors, __array_errors.items, ), @@ -75,7 +75,7 @@ pub fn object_errors_tokens() -> TokenStream { pub fn array_errors_tokens() -> TokenStream { quote!(::serde_valid::validation::Errors::Array( - ::serde_valid::validation::ArrayErrors::new( + ::serde_valid::validation::error::ArrayErrors::new( __rule_vec_errors, __item_vec_errors_map .into_iter() @@ -119,7 +119,7 @@ pub fn array_errors_tokens() -> TokenStream { ( index, ::serde_valid::validation::Errors::Array( - ::serde_valid::validation::ArrayErrors::new( + ::serde_valid::validation::error::ArrayErrors::new( __field_errors, __array_errors.items, ), From ba6dd2103acf3271c9055de6197d731d97448827 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Thu, 11 Jan 2024 22:02:51 +0900 Subject: [PATCH 11/25] chore: add expads folder. --- serde_valid/expands/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 serde_valid/expands/.gitignore diff --git a/serde_valid/expands/.gitignore b/serde_valid/expands/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/serde_valid/expands/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore From eeed49bc3c4c9ba2ee8b9cd051d34bf97d9e67e6 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Fri, 12 Jan 2024 00:06:12 +0900 Subject: [PATCH 12/25] refactor: message format. --- .../src/features/flatten/flat_errors.rs | 4 +- serde_valid/src/features/flatten/into_flat.rs | 18 +- serde_valid/src/features/fluent.rs | 3 +- .../src/features/fluent/into_localization.rs | 212 ----------------- serde_valid/src/features/fluent/localize.rs | 224 ++++++++++++++++++ serde_valid/src/validation/error/format.rs | 42 +--- .../src/validation/error/into_error.rs | 11 +- serde_valid/src/validation/error/message.rs | 36 +-- .../src/attribute/field_validate.rs | 2 +- .../field_validate/array/length_items.rs | 12 +- .../field_validate/array/unique_items.rs | 13 +- .../src/attribute/field_validate/common.rs | 4 +- .../{custom_message.rs => message_format.rs} | 112 +++------ .../field_validate/generic/custom.rs | 5 +- .../field_validate/generic/enumerate.rs | 11 +- .../src/attribute/field_validate/meta.rs | 24 +- .../field_validate/meta/meta_list.rs | 8 +- .../field_validate/meta/meta_name_value.rs | 28 +-- .../field_validate/meta/meta_path.rs | 6 +- .../field_validate/numeric/multiple_of.rs | 11 +- .../attribute/field_validate/numeric/range.rs | 13 +- .../field_validate/object/size_properties.rs | 13 +- .../attribute/field_validate/string/length.rs | 13 +- .../field_validate/string/pattern.rs | 15 +- .../struct_validate/generic/custom.rs | 8 +- .../src/attribute/struct_validate/meta.rs | 23 +- .../struct_validate/meta/meta_list.rs | 6 +- .../struct_validate/meta/meta_name_value.rs | 6 +- .../struct_validate/meta/meta_path.rs | 4 +- 29 files changed, 407 insertions(+), 480 deletions(-) delete mode 100644 serde_valid/src/features/fluent/into_localization.rs create mode 100644 serde_valid/src/features/fluent/localize.rs rename serde_valid_derive/src/attribute/field_validate/common/{custom_message.rs => message_format.rs} (56%) diff --git a/serde_valid/src/features/flatten/flat_errors.rs b/serde_valid/src/features/flatten/flat_errors.rs index 4081fdd..6be0203 100644 --- a/serde_valid/src/features/flatten/flat_errors.rs +++ b/serde_valid/src/features/flatten/flat_errors.rs @@ -51,7 +51,7 @@ mod tests { use crate::{ flatten::IntoFlat, - validation::error::{ArrayErrors, DefaultFormat, Message}, + validation::error::{ArrayErrors, Message}, validation::{Error, Errors}, MinItemsError, }; @@ -63,7 +63,7 @@ mod tests { Errors::Array(ArrayErrors { errors: vec![Error::MinItems(Message::new( MinItemsError { min_items: 1 }, - MinItemsError::default_format + crate::validation::error::Format::Default ))], items: indexmap! {}, }) diff --git a/serde_valid/src/features/flatten/into_flat.rs b/serde_valid/src/features/flatten/into_flat.rs index 1963952..7194219 100644 --- a/serde_valid/src/features/flatten/into_flat.rs +++ b/serde_valid/src/features/flatten/into_flat.rs @@ -112,7 +112,7 @@ where T: DefaultFormat, { fn into_flat_at(self, path: &JSONPointer) -> FlatErrors { - FlatErrors::new(vec![FlatError::new(path.to_owned(), self.error())]) + FlatErrors::new(vec![FlatError::new(path.to_owned(), self.to_string())]) } } @@ -168,13 +168,13 @@ mod tests { fn array_errors_flatten() { let min_items = Message::new( MinItemsError { min_items: 1 }, - MinItemsError::default_format, + crate::validation::error::Format::Default, ); let maximum = Message::new( MaximumError { maximum: Number::I32(1), }, - MaximumError::default_format, + crate::validation::error::Format::Default, ); assert_eq!( Errors::Array(ArrayErrors { @@ -203,29 +203,29 @@ mod tests { FlatErrors::new(vec![ FlatError::new( JSONPointer::default(), - min_items.error().default_format(), + min_items.to_string(), ), FlatError::new( JSONPointer::from([PathChunk::from(0)].as_ref()), - maximum.error().default_format(), + maximum.to_string(), ), FlatError::new( JSONPointer::from([PathChunk::from(0), PathChunk::from(2)].as_ref()), - maximum.error().default_format(), + maximum.to_string(), ), FlatError::new( JSONPointer::from([PathChunk::from(3)].as_ref()), - maximum.error().default_format(), + maximum.to_string(), ), FlatError::new( JSONPointer::from([PathChunk::from(5)].as_ref()), - maximum.error().default_format(), + maximum.to_string(), ), FlatError::new( JSONPointer::from( [PathChunk::from(5), PathChunk::from("name".to_owned())].as_ref() ), - maximum.error().default_format(), + maximum.to_string(), ) ]) ); diff --git a/serde_valid/src/features/fluent.rs b/serde_valid/src/features/fluent.rs index 93037f4..b35172d 100644 --- a/serde_valid/src/features/fluent.rs +++ b/serde_valid/src/features/fluent.rs @@ -1,5 +1,4 @@ -mod into_localization; +mod localize; mod message; -pub use into_localization::IntoLocalization; pub use message::Message; diff --git a/serde_valid/src/features/fluent/into_localization.rs b/serde_valid/src/features/fluent/into_localization.rs deleted file mode 100644 index 45ac1bb..0000000 --- a/serde_valid/src/features/fluent/into_localization.rs +++ /dev/null @@ -1,212 +0,0 @@ -use fluent_0::{FluentArgs, FluentBundle, FluentResource}; - -use crate::validation::error::{ - ArrayErrors, Errors, ItemErrorsMap, ObjectErrors, PropertyErrorsMap, VecErrors, -}; - -pub trait IntoLocalization { - type Target; - - fn into_localization(self, bundle: &FluentBundle) -> Self::Target; -} - -impl IntoLocalization for Errors { - type Target = Errors; - - fn into_localization(self, bundle: &FluentBundle) -> Self::Target { - match self { - Errors::Array(array) => Errors::Array(array.into_localization(bundle)), - Errors::Object(object) => Errors::Object(object.into_localization(bundle)), - Errors::NewType(newtype) => Errors::NewType(newtype.into_localization(bundle)), - } - } -} - -impl IntoLocalization for ArrayErrors { - type Target = ArrayErrors; - - fn into_localization(self, bundle: &FluentBundle) -> Self::Target { - ArrayErrors { - errors: self.errors.into_localization(bundle), - items: self.items.into_localization(bundle), - } - } -} - -impl IntoLocalization for ObjectErrors { - type Target = ObjectErrors; - - fn into_localization(self, bundle: &FluentBundle) -> Self::Target { - ObjectErrors { - errors: self.errors.into_localization(bundle), - properties: self.properties.into_localization(bundle), - } - } -} - -impl IntoLocalization for VecErrors { - type Target = VecErrors; - - fn into_localization(self, bundle: &FluentBundle) -> Self::Target { - self.into_iter() - .map(|error| error.into_localization(bundle)) - .collect() - } -} - -impl IntoLocalization for ItemErrorsMap { - type Target = ItemErrorsMap; - - fn into_localization(self, bundle: &FluentBundle) -> Self::Target { - self.into_iter() - .map(|(index, error)| (index, error.into_localization(bundle))) - .collect() - } -} - -impl IntoLocalization for PropertyErrorsMap { - type Target = PropertyErrorsMap; - - fn into_localization(self, bundle: &FluentBundle) -> Self::Target { - self.into_iter() - .map(|(property, error)| (property, error.into_localization(bundle))) - .collect() - } -} - -impl IntoLocalization for crate::validation::Error { - type Target = String; - - fn into_localization(self, bundle: &FluentBundle) -> Self::Target { - match self { - Self::Minimum(message) => localize_or_default(&message, bundle), - Self::Maximum(message) => localize_or_default(&message, bundle), - Self::ExclusiveMinimum(message) => localize_or_default(&message, bundle), - Self::ExclusiveMaximum(message) => localize_or_default(&message, bundle), - Self::MultipleOf(message) => localize_or_default(&message, bundle), - Self::MinLength(message) => localize_or_default(&message, bundle), - Self::MaxLength(message) => localize_or_default(&message, bundle), - Self::Pattern(message) => localize_or_default(&message, bundle), - Self::MinItems(message) => localize_or_default(&message, bundle), - Self::MaxItems(message) => localize_or_default(&message, bundle), - Self::UniqueItems(message) => localize_or_default(&message, bundle), - Self::MinProperties(message) => localize_or_default(&message, bundle), - Self::MaxProperties(message) => localize_or_default(&message, bundle), - Self::Enumerate(message) => localize_or_default(&message, bundle), - Self::Custom(message) => message, - Self::Items(message) => format!("{message}"), - Self::Properties(message) => format!("{message}"), - Self::Fluent(message) => { - localize(Some(&message), bundle).unwrap_or_else(|| format!("{message}")) - } - } - } -} - -fn localize( - message: Option<&crate::fluent::Message>, - bundle: &FluentBundle, -) -> Option { - if let Some(fluent_message) = message { - if let Some(msg) = bundle.get_message(fluent_message.id) { - if let Some(pattern) = msg.value() { - let mut errors = vec![]; - let args = FluentArgs::from_iter(fluent_message.args.to_owned()); - let value = bundle - .format_pattern(pattern, Some(&args), &mut errors) - .to_string(); - - if errors.is_empty() { - return Some(value); - } - } - } - } - None -} - -fn localize_or_default( - message: &crate::validation::error::Message, - bundle: &FluentBundle, -) -> String { - if let Some(value) = localize(message.fluent_message.as_ref(), bundle) { - value - } else { - format!("{message}") - } -} - -#[cfg(test)] -mod test { - use crate::{fluent::Message, validation::error::Format}; - - use super::*; - use fluent_0::{FluentResource, FluentValue}; - use serde_valid_literal::Number; - use unic_langid::LanguageIdentifier; - - #[test] - fn into_localization_without_args() { - let ftl_string = "hello-world = Hello, world!".to_string(); - let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); - - let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); - let mut bundle = FluentBundle::new(vec![langid_en]); - bundle.add_resource(res).unwrap(); - - let error = crate::validation::Error::Fluent(Message { - id: "hello-world", - args: vec![], - }); - - assert_eq!(error.into_localization(&bundle), "Hello, world!"); - } - - #[test] - fn into_localization_with_args() { - let ftl_string = "intro = Welcome, { $name }.".to_string(); - let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); - - let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); - let mut bundle = FluentBundle::new(vec![langid_en]); - bundle.add_resource(res).unwrap(); - - let error = crate::validation::Error::Fluent(Message { - id: "intro", - args: vec![("name", FluentValue::from("John"))], - }); - - assert_eq!( - error.into_localization(&bundle), - "Welcome, \u{2068}John\u{2069}." - ); - } - - #[test] - fn into_localization_from_validation_error() { - let ftl_string = "intro = Welcome, { $name }.".to_string(); - let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); - - let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); - let mut bundle = FluentBundle::new(vec![langid_en]); - bundle.add_resource(res).unwrap(); - - let error = crate::validation::Error::Maximum( - Format { - message_fn: crate::validation::error::DefaultFormat::default_format, - fluent_message: Some(Message { - id: "intro", - args: vec![("name", FluentValue::from("John"))], - }), - } - .into_message(crate::MaximumError { - maximum: Number::I32(10), - }), - ); - - assert_eq!( - error.into_localization(&bundle), - "Welcome, \u{2068}John\u{2069}." - ); - } -} diff --git a/serde_valid/src/features/fluent/localize.rs b/serde_valid/src/features/fluent/localize.rs new file mode 100644 index 0000000..8abb53a --- /dev/null +++ b/serde_valid/src/features/fluent/localize.rs @@ -0,0 +1,224 @@ +// use fluent_0::{FluentArgs, FluentBundle, FluentError, FluentResource}; + +// use crate::validation::error::{ +// ArrayErrors, DefaultFormat, Errors, ItemErrorsMap, ObjectErrors, PropertyErrorsMap, VecErrors, +// }; + +// pub trait Localize { +// type Target; + +// fn localize(self, bundle: &FluentBundle) -> Self::Target; +// } + +// impl Localize for Errors { +// type Target = Errors; + +// fn localize(self, bundle: &FluentBundle) -> Self::Target { +// match self { +// Errors::Array(array) => Errors::Array(array.localize(bundle)), +// Errors::Object(object) => Errors::Object(object.localize(bundle)), +// Errors::NewType(newtype) => Errors::NewType(newtype.localize(bundle)), +// } +// } +// } + +// impl Localize for ArrayErrors { +// type Target = ArrayErrors; + +// fn localize(self, bundle: &FluentBundle) -> Self::Target { +// ArrayErrors { +// errors: self.errors.localize(bundle), +// items: self.items.localize(bundle), +// } +// } +// } + +// impl Localize for ObjectErrors { +// type Target = ObjectErrors; + +// fn localize(self, bundle: &FluentBundle) -> Self::Target { +// ObjectErrors { +// errors: self.errors.localize(bundle), +// properties: self.properties.localize(bundle), +// } +// } +// } + +// impl Localize for VecErrors { +// type Target = VecErrors; + +// fn localize(self, bundle: &FluentBundle) -> Self::Target { +// self.into_iter() +// .map(|error| error.localize(bundle)) +// .collect() +// } +// } + +// impl Localize for ItemErrorsMap { +// type Target = ItemErrorsMap; + +// fn localize(self, bundle: &FluentBundle) -> Self::Target { +// self.into_iter() +// .map(|(index, error)| (index, error.localize(bundle))) +// .collect::() +// } +// } + +// impl Localize for PropertyErrorsMap { +// type Target = PropertyErrorsMap; + +// fn localize(self, bundle: &FluentBundle) -> Self::Target { +// self.into_iter() +// .map(|(index, error)| (index, error.localize(bundle))) +// .collect::() +// } +// } + +// impl Localize for crate::validation::Error { +// type Target = String; + +// fn localize(self, bundle: &FluentBundle) -> Self::Target { +// match self { +// Self::Minimum(message) => localize_or_default(&message, bundle), +// Self::Maximum(message) => localize_or_default(&message, bundle), +// Self::ExclusiveMinimum(message) => localize_or_default(&message, bundle), +// Self::ExclusiveMaximum(message) => localize_or_default(&message, bundle), +// Self::MultipleOf(message) => localize_or_default(&message, bundle), +// Self::MinLength(message) => localize_or_default(&message, bundle), +// Self::MaxLength(message) => localize_or_default(&message, bundle), +// Self::Pattern(message) => localize_or_default(&message, bundle), +// Self::MinItems(message) => localize_or_default(&message, bundle), +// Self::MaxItems(message) => localize_or_default(&message, bundle), +// Self::UniqueItems(message) => localize_or_default(&message, bundle), +// Self::MinProperties(message) => localize_or_default(&message, bundle), +// Self::MaxProperties(message) => localize_or_default(&message, bundle), +// Self::Enumerate(message) => localize_or_default(&message, bundle), +// Self::Custom(message) => message, +// Self::Items(message) => format!("{message}"), +// Self::Properties(message) => format!("{message}"), +// Self::Fluent(message) => localize(&message, bundle), +// } +// } +// } + +// fn try_localize( +// message: &crate::validation::error::Message, +// bundle: &FluentBundle, +// ) -> Result, Vec> { +// if let Some(msg) = bundle.get_message(message.id) { +// if let Some(pattern) = msg.value() { +// let mut errors = vec![]; +// let args = FluentArgs::from_iter(message.args.to_owned()); +// let value = bundle +// .format_pattern(pattern, Some(&args), &mut errors) +// .to_string(); + +// if !errors.is_empty() { +// return Ok(Some(value)); +// } else { +// return Err(errors); +// } +// } +// } + +// Ok(None) +// } + +// fn localize( +// message: &crate::validation::error::Message, +// bundle: &FluentBundle, +// ) -> Option { +// try_localize(message, bundle).unwrap_or_else(|_| Some(message.to_string())) +// } + +// fn try_localize_or_default( +// message: &crate::validation::error::Message, +// bundle: &FluentBundle, +// ) -> Result> { +// if let Some(fluent_message) = message.fluent_message() { +// if let Some(value) = try_localize(fluent_message, bundle)? { +// return Ok(value); +// } +// } + +// Ok(format!("{message}")) +// } + +// fn localize_or_default( +// message: &crate::validation::error::Message, +// bundle: &FluentBundle, +// ) -> String { +// try_localize_or_default(message, bundle).unwrap_or_else(|_| message.to_string()) +// } + +// #[cfg(test)] +// mod test { +// use crate::{fluent::Message, validation::error::Format}; + +// use super::*; +// use fluent_0::{FluentResource, FluentValue}; +// use serde_valid_literal::Number; +// use unic_langid::LanguageIdentifier; + +// #[test] +// fn try_localize_without_args() { +// let ftl_string = "hello-world = Hello, world!".to_string(); +// let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); + +// let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); +// let mut bundle = FluentBundle::new(vec![langid_en]); +// bundle.add_resource(res).unwrap(); + +// let error = crate::validation::Error::Fluent(Message { +// id: "hello-world", +// args: vec![], +// }); + +// assert_eq!(error.try_localize(&bundle), Ok("Hello, world!".to_string())); +// } + +// #[test] +// fn try_localize_with_args() { +// let ftl_string = "intro = Welcome, { $name }.".to_string(); +// let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); + +// let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); +// let mut bundle = FluentBundle::new(vec![langid_en]); +// bundle.add_resource(res).unwrap(); + +// let error = crate::validation::Error::Fluent(Message { +// id: "intro", +// args: vec![("name", FluentValue::from("John"))], +// }); + +// assert_eq!( +// error.try_localize(&bundle), +// Ok("Welcome, \u{2068}John\u{2069}.".to_string()) +// ); +// } + +// #[test] +// fn try_localize_from_validation_error() { +// let ftl_string = "intro = Welcome, { $name }.".to_string(); +// let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); + +// let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); +// let mut bundle = FluentBundle::new(vec![langid_en]); +// bundle.add_resource(res).unwrap(); + +// let error = crate::validation::Error::Maximum( +// Format::Fluent(Message { +// id: "intro", +// args: vec![("name", FluentValue::from("John"))], +// }) +// .into_message(crate::MaximumError { +// maximum: Number::I32(10), +// }), +// ); + +// assert_eq!( +// error.try_localize(&bundle), +// Ok("Welcome, \u{2068}John\u{2069}.".to_string()) +// ); +// } +// } diff --git a/serde_valid/src/validation/error/format.rs b/serde_valid/src/validation/error/format.rs index 2fd954f..c530682 100644 --- a/serde_valid/src/validation/error/format.rs +++ b/serde_valid/src/validation/error/format.rs @@ -1,43 +1,21 @@ #[derive(Clone)] -pub struct Format { - pub message_fn: fn(&E) -> String, +pub enum Format { + Default, + Message(String), + MessageFn(fn(&E) -> String), #[cfg(feature = "fluent")] - pub fluent_message: Option, + Fluent(crate::fluent::Message), } impl Format { - #[cfg(feature = "fluent")] - pub fn into_message(self, error: E) -> crate::validation::error::Message { - let mut message = crate::validation::error::Message::new(error, self.message_fn); - message.fluent_message = self.fluent_message; - message - } - - #[cfg(not(feature = "fluent"))] - pub fn into_message(self, error: E) -> crate::validation::error::Message { - crate::validation::error::Message::new(error, self.message_fn) - } -} - -impl Default for Format -where - E: crate::validation::error::DefaultFormat, -{ - fn default() -> Self { - Self { - message_fn: crate::validation::error::DefaultFormat::default_format, - #[cfg(feature = "fluent")] - fluent_message: None, - } + pub fn into_message(self, error: E) -> crate::validation::error::Message + where + E: DefaultFormat, + { + crate::validation::error::Message::new(error, self) } } pub trait DefaultFormat { fn default_format(&self) -> String; } - -impl DefaultFormat for String { - fn default_format(&self) -> String { - self.into() - } -} diff --git a/serde_valid/src/validation/error/into_error.rs b/serde_valid/src/validation/error/into_error.rs index 4a643c5..b149a2b 100644 --- a/serde_valid/src/validation/error/into_error.rs +++ b/serde_valid/src/validation/error/into_error.rs @@ -1,18 +1,13 @@ use crate::validation::error::DefaultFormat; -use super::Format; - pub trait IntoError: Sized where E: DefaultFormat, { fn into_error(self) -> crate::validation::Error { - self.into_error_by(Format { - message_fn: E::default_format, - #[cfg(feature = "fluent")] - fluent_message: None, - }) + self.into_error_by(crate::validation::error::Format::Default) } - fn into_error_by(self, custom: Format) -> crate::validation::Error; + fn into_error_by(self, format: crate::validation::error::Format) + -> crate::validation::Error; } diff --git a/serde_valid/src/validation/error/message.rs b/serde_valid/src/validation/error/message.rs index 7f01949..8aaa88d 100644 --- a/serde_valid/src/validation/error/message.rs +++ b/serde_valid/src/validation/error/message.rs @@ -1,23 +1,22 @@ +use super::{DefaultFormat, Format}; + #[derive(Clone)] pub struct Message { error: E, - format_fn: for<'a> fn(&'a E) -> String, - #[cfg(feature = "fluent")] - pub fluent_message: Option, + format: Format, } impl Message { - pub fn new(error: E, format_fn: fn(&E) -> String) -> Self { - Self { - error, - format_fn, - #[cfg(feature = "fluent")] - fluent_message: None, - } + pub fn new(error: E, format: Format) -> Self { + Self { error, format } } - pub fn error(&self) -> String { - (self.format_fn)(&self.error) + #[cfg(feature = "fluent")] + pub fn fluent_message(&self) -> Option<&crate::features::fluent::Message> { + match self.format { + Format::Fluent(ref message) => Some(message), + _ => None, + } } } @@ -30,8 +29,17 @@ where } } -impl std::fmt::Display for Message { +impl std::fmt::Display for Message +where + E: DefaultFormat, +{ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", { self.format_fn }(&self.error)) + match self.format { + Format::Default => write!(f, "{}", self.error.default_format()), + Format::Message(ref message) => write!(f, "{message}"), + Format::MessageFn(ref format_fn) => write!(f, "{}", { format_fn }(&self.error)), + #[cfg(feature = "fluent")] + Format::Fluent(_) => write!(f, "{}", self.error.default_format()), + } } } diff --git a/serde_valid_derive/src/attribute/field_validate.rs b/serde_valid_derive/src/attribute/field_validate.rs index c5296fc..018a3f1 100644 --- a/serde_valid_derive/src/attribute/field_validate.rs +++ b/serde_valid_derive/src/attribute/field_validate.rs @@ -8,7 +8,7 @@ mod object; mod string; pub use common::{ - extract_custom_message_tokens, CustomMessageToken, MetaListCustomMessage, + default_message_format, extract_custom_message_format, MessageFormat, MetaListCustomMessage, MetaListFieldValidation, MetaListStructValidation, MetaNameValueCustomMessage, MetaNameValueFieldValidation, MetaNameValueStructValidation, MetaPathCustomMessage, MetaPathFieldValidation, MetaPathStructValidation, diff --git a/serde_valid_derive/src/attribute/field_validate/array/length_items.rs b/serde_valid_derive/src/attribute/field_validate/array/length_items.rs index cd2d532..b6ebea3 100644 --- a/serde_valid_derive/src/attribute/field_validate/array/length_items.rs +++ b/serde_valid_derive/src/attribute/field_validate/array/length_items.rs @@ -1,5 +1,5 @@ use crate::attribute::field_validate::common::get_numeric; -use crate::attribute::field_validate::{common::CustomMessageToken, Validator}; +use crate::attribute::field_validate::{common::MessageFormat, Validator}; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; @@ -14,16 +14,16 @@ macro_rules! extract_array_length_validator{ pub fn []( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { - [](field, validation_value, custom_message, rename_map) + [](field, validation_value, message_format, rename_map) } fn []( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { let field_name = field.name(); @@ -32,8 +32,6 @@ macro_rules! extract_array_length_validator{ let rename = rename_map.get(field_name).unwrap_or(&field_key); let [<$ErrorType:snake>] = get_numeric(validation_value)?; let errors = field.errors_variable(); - let message_fn = custom_message - .message_fn.unwrap_or(quote!(::serde_valid::[<$ErrorType Error>]::default_format)); Ok(quote!( if let Err(error_params) = ::serde_valid::[]::[]( @@ -48,7 +46,7 @@ macro_rules! extract_array_length_validator{ .push(::serde_valid::validation::Error::$ErrorType( ::serde_valid::validation::error::Message::new( error_params, - #message_fn, + #message_format, ) )); } diff --git a/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs b/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs index 865e572..30e20b1 100644 --- a/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs +++ b/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs @@ -1,4 +1,4 @@ -use crate::attribute::field_validate::{common::CustomMessageToken, Validator}; +use crate::attribute::field_validate::{common::MessageFormat, Validator}; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; @@ -6,15 +6,15 @@ use quote::quote; pub fn extract_array_unique_items_validator( field: &impl Field, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Validator { - inner_extract_array_unique_items_validator(field, custom_message, rename_map) + inner_extract_array_unique_items_validator(field, message_format, rename_map) } fn inner_extract_array_unique_items_validator( field: &impl Field, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> TokenStream { let field_name = field.name(); @@ -22,9 +22,6 @@ fn inner_extract_array_unique_items_validator( let field_key = field.key(); let rename = rename_map.get(field_name).unwrap_or(&field_key); let errors = field.errors_variable(); - let message_fn = custom_message - .message_fn - .unwrap_or(quote!(::serde_valid::UniqueItemsError::default_format)); quote!( if let Err(error_params) = ::serde_valid::ValidateUniqueItems::validate_unique_items( @@ -38,7 +35,7 @@ fn inner_extract_array_unique_items_validator( .push(::serde_valid::validation::Error::UniqueItems( ::serde_valid::validation::error::Message::new( error_params, - #message_fn, + #message_format, ) )); } diff --git a/serde_valid_derive/src/attribute/field_validate/common.rs b/serde_valid_derive/src/attribute/field_validate/common.rs index 796d5b5..7e313ac 100644 --- a/serde_valid_derive/src/attribute/field_validate/common.rs +++ b/serde_valid_derive/src/attribute/field_validate/common.rs @@ -1,8 +1,8 @@ -mod custom_message; mod lit; +mod message_format; -pub use custom_message::{extract_custom_message_tokens, CustomMessageToken}; pub use lit::{get_lit, get_numeric, get_str}; +pub use message_format::{default_message_format, extract_custom_message_format, MessageFormat}; macro_rules! count { () => (0usize); diff --git a/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs b/serde_valid_derive/src/attribute/field_validate/common/message_format.rs similarity index 56% rename from serde_valid_derive/src/attribute/field_validate/common/custom_message.rs rename to serde_valid_derive/src/attribute/field_validate/common/message_format.rs index 9f03f41..34a1b11 100644 --- a/serde_valid_derive/src/attribute/field_validate/common/custom_message.rs +++ b/serde_valid_derive/src/attribute/field_validate/common/message_format.rs @@ -5,64 +5,13 @@ use std::str::FromStr; use super::{get_str, MetaListCustomMessage, MetaNameValueCustomMessage, MetaPathCustomMessage}; -#[derive(Debug, Default)] -pub struct CustomMessageToken { - pub message_fn: Option, - #[cfg(feature = "fluent")] - pub fluent_message: Option, -} - -impl CustomMessageToken { - pub fn new_message_fn(message_fn: TokenStream) -> Self { - Self { - message_fn: Some(message_fn), - #[cfg(feature = "fluent")] - fluent_message: None, - } - } - - #[cfg(feature = "fluent")] - pub fn new_fluent_message(fluent_message: TokenStream) -> Self { - Self { - message_fn: None, - fluent_message: Some(fluent_message), - } - } - - #[cfg(not(feature = "fluent"))] - pub fn into_token(self) -> TokenStream { - match self.message_fn { - Some(message_fn) => quote!( - Some(::serde_valid::validation::error::Format{ - message_fn: #message_fn, - }) - ), - None => quote!(None), - } - } - - #[cfg(feature = "fluent")] - pub fn into_token(self) -> TokenStream { - if self.message_fn.is_none() && self.fluent_message.is_none() { - return quote!(None); - } - - let message_fn = self.message_fn.unwrap_or(quote!( - ::serde_valid::validation::error::DefaultFormat::default_format - )); +pub type MessageFormat = TokenStream; - quote!( - Some(::serde_valid::validation::error::Format{ - message_fn: #message_fn, - fluent_message: None, - }) - ) - } +pub fn default_message_format() -> MessageFormat { + quote!(::serde_valid::validation::error::Format::Default) } -pub fn extract_custom_message_tokens( - meta: &syn::Meta, -) -> Result { +pub fn extract_custom_message_format(meta: &syn::Meta) -> Result { let custom_message_path = match meta { syn::Meta::Path(path) => path, syn::Meta::List(list) => &list.path, @@ -81,12 +30,12 @@ pub fn extract_custom_message_tokens( (Ok(_), _, _, syn::Meta::Path(_)) => { unreachable!() } - (_, Ok(custom_message_type), _, syn::Meta::List(custom_message)) => { - extract_custom_message_tokens_from_meta_list(&custom_message_type, custom_message) - } - (_, _, Ok(custom_message_type), syn::Meta::NameValue(custom_message)) => { - extract_custom_message_tokens_from_name_value(&custom_message_type, custom_message) - } + (_, Ok(custom_message_type), _, syn::Meta::List(custom_message)) => Ok( + extract_custom_message_format_from_meta_list(&custom_message_type, custom_message)?, + ), + (_, _, Ok(custom_message_type), syn::Meta::NameValue(custom_message)) => Ok( + extract_custom_message_format_from_name_value(&custom_message_type, custom_message)?, + ), (Ok(_), _, _, _) => Err(vec![crate::Error::meta_path_custom_message_need_value( custom_message_path, &custom_message_name, @@ -108,10 +57,10 @@ pub fn extract_custom_message_tokens( } } -fn extract_custom_message_tokens_from_meta_list( +fn extract_custom_message_format_from_meta_list( custom_message_type: &MetaListCustomMessage, meta_list: &syn::MetaList, -) -> Result { +) -> Result { let path = &meta_list.path; let path_ident = SingleIdentPath::new(path).ident(); let message_fn_define = meta_list @@ -119,25 +68,20 @@ fn extract_custom_message_tokens_from_meta_list( .map_err(|error| vec![crate::Error::custom_message_parse_error(path_ident, &error)])?; match custom_message_type { - MetaListCustomMessage::MessageFn => { - get_message_fn(path, &message_fn_define).map(CustomMessageToken::new_message_fn) - } + MetaListCustomMessage::MessageFn => get_message_fn(path, &message_fn_define), #[cfg(feature = "fluent")] message_type @ (MetaListCustomMessage::I18n | MetaListCustomMessage::Fluent) => { get_fluent_message(message_type, path, &message_fn_define) - .map(CustomMessageToken::new_fluent_message) } } } -fn extract_custom_message_tokens_from_name_value( +fn extract_custom_message_format_from_name_value( custom_message_type: &MetaNameValueCustomMessage, name_value: &syn::MetaNameValue, -) -> Result { +) -> Result { match custom_message_type { - MetaNameValueCustomMessage::Message => { - get_message(&name_value.value).map(CustomMessageToken::new_message_fn) - } + MetaNameValueCustomMessage::Message => get_message(&name_value.value), } } @@ -145,27 +89,27 @@ fn get_message_fn( path: &syn::Path, fn_define: &CommaSeparatedNestedMetas, ) -> Result { - match fn_define.len() { + let fn_name = match fn_define.len() { 0 => Err(vec![crate::Error::message_fn_need_item(path)]), - 1 => { - let fn_name = match &fn_define[0] { - NestedMeta::Meta(syn::Meta::Path(fn_name)) => Some(quote!(#fn_name)), - _ => None, - }; - fn_name.ok_or_else(|| vec![crate::Error::message_fn_allow_name_path(&fn_define[0])]) + 1 => match &fn_define[0] { + NestedMeta::Meta(syn::Meta::Path(fn_name)) => Some(quote!(#fn_name)), + _ => None, } + .ok_or_else(|| vec![crate::Error::message_fn_allow_name_path(&fn_define[0])]), _ => Err(fn_define .iter() .skip(1) .map(crate::Error::message_fn_tail_error) .collect()), - } + }?; + + Ok(quote!(::serde_valid::validation::error::Format::MessageFn(#fn_name))) } fn get_message(expr: &syn::Expr) -> Result { match expr { syn::Expr::Lit(lit) => { - get_str(&lit.lit).map(|lit_str| quote!(|_| { #lit_str.to_string() })) + get_str(&lit.lit).map(|lit_str| quote!(::serde_valid::validation::error::Format::Message(#lit_str.to_string()))) } _ => Err(vec![crate::Error::literal_only(expr)]), } @@ -176,15 +120,17 @@ fn get_fluent_message( message_type: &MetaListCustomMessage, path: &syn::Path, fn_define: &CommaSeparatedNestedMetas, -) -> Result { +) -> Result { match fn_define.len() { 0 => Err(vec![crate::Error::fluent_need_item(message_type, path)]), 1 => match &fn_define[0] { NestedMeta::Lit(syn::Lit::Str(id)) => Ok(quote!( - ::serde_valid::fluent::Message{ + ::serde_valid::validation::error::Format::Fluent( + ::serde_valid::fluent::Message{ id: #id, args: vec![] } + ) )), _ => Err(vec![crate::Error::fluent_allow_key( message_type, diff --git a/serde_valid_derive/src/attribute/field_validate/generic/custom.rs b/serde_valid_derive/src/attribute/field_validate/generic/custom.rs index 033d05c..3b42598 100644 --- a/serde_valid_derive/src/attribute/field_validate/generic/custom.rs +++ b/serde_valid_derive/src/attribute/field_validate/generic/custom.rs @@ -1,4 +1,5 @@ -use crate::attribute::field_validate::{CustomMessageToken, Validator}; +use crate::attribute::field_validate::common::MessageFormat; +use crate::attribute::field_validate::Validator; use crate::serde::rename::RenameMap; use crate::types::{CommaSeparatedNestedMetas, Field, SingleIdentPath}; use proc_macro2::TokenStream; @@ -7,7 +8,7 @@ use quote::quote; pub fn extract_generic_custom_validator( field: &impl Field, meta_list: &syn::MetaList, - _custom_message: CustomMessageToken, + _message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { let path = &meta_list.path; diff --git a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs index 08e14eb..1fd75c4 100644 --- a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs +++ b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs @@ -1,4 +1,4 @@ -use crate::attribute::field_validate::common::CustomMessageToken; +use crate::attribute::field_validate::common::MessageFormat; use crate::attribute::field_validate::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; @@ -9,16 +9,16 @@ type Lits<'a> = syn::punctuated::Punctuated; pub fn extract_generic_enumerate_validator( field: &impl Field, item_list: &syn::MetaList, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { - inner_extract_generic_enumerate_validator(field, item_list, custom_message, rename_map) + inner_extract_generic_enumerate_validator(field, item_list, message_format, rename_map) } fn inner_extract_generic_enumerate_validator( field: &impl Field, item_list: &syn::MetaList, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { let field_name = field.name(); @@ -27,7 +27,6 @@ fn inner_extract_generic_enumerate_validator( let rename = rename_map.get(field_name).unwrap_or(&field_key); let errors = field.errors_variable(); let enumerate = get_enumerate(item_list)?; - let custom_message = custom_message.into_token(); Ok(quote!( if let Err(__composited_error_params) = ::serde_valid::validation::ValidateCompositedEnumerate::validate_composited_enumerate( @@ -40,7 +39,7 @@ fn inner_extract_generic_enumerate_validator( #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); + .push(__composited_error_params.into_error_by(#message_format)); } )) } diff --git a/serde_valid_derive/src/attribute/field_validate/meta.rs b/serde_valid_derive/src/attribute/field_validate/meta.rs index 6010a13..05ba581 100644 --- a/serde_valid_derive/src/attribute/field_validate/meta.rs +++ b/serde_valid_derive/src/attribute/field_validate/meta.rs @@ -2,7 +2,7 @@ mod meta_list; mod meta_name_value; mod meta_path; -use crate::attribute::field_validate::common::{extract_custom_message_tokens, CustomMessageToken}; +use crate::attribute::field_validate::common::extract_custom_message_format; use crate::attribute::field_validate::{ MetaListFieldValidation, MetaNameValueFieldValidation, MetaPathFieldValidation, Validator, }; @@ -14,6 +14,7 @@ use meta_name_value::extract_field_validator_from_meta_name_value; use meta_path::extract_field_validator_from_meta_path; use std::str::FromStr; +use super::common::default_message_format; use super::generic::extract_generic_validate_validator; pub fn extract_field_validator( @@ -47,25 +48,26 @@ fn inner_extract_field_validator( )] })?; - let custom_message = match nested.len() { + let message_format = match nested.len() { 0 => Err(vec![crate::Error::field_validation_type_required( attribute, )])?, - 1 => CustomMessageToken::default(), - 2 => match extract_custom_message_tokens(&nested[1]) { - Ok(custom_message) => custom_message, + 1 => None, + 2 => match extract_custom_message_format(&nested[1]) { + Ok(custom_message) => Some(custom_message), Err(message_fn_errors) => { errors.extend(message_fn_errors); - CustomMessageToken::default() + None } }, _ => { for meta in nested.iter().skip(2) { errors.push(crate::Error::too_many_list_items(meta)); } - CustomMessageToken::default() + None } - }; + } + .unwrap_or_else(default_message_format); let meta = &nested[0]; @@ -88,7 +90,7 @@ fn inner_extract_field_validator( field, validation_type, validation, - custom_message, + message_format, rename_map, ) } @@ -98,7 +100,7 @@ fn inner_extract_field_validator( field, validation_type, validation, - custom_message, + message_format, rename_map, ) } @@ -108,7 +110,7 @@ fn inner_extract_field_validator( field, validation_type, validation, - custom_message, + message_format, rename_map, ) } diff --git a/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs b/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs index 6218b8a..c4e4c59 100644 --- a/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs +++ b/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs @@ -1,4 +1,4 @@ -use crate::attribute::field_validate::common::{CustomMessageToken, MetaListFieldValidation}; +use crate::attribute::field_validate::common::{MessageFormat, MetaListFieldValidation}; use crate::attribute::field_validate::generic::{ extract_generic_custom_validator, extract_generic_enumerate_validator, }; @@ -10,15 +10,15 @@ pub fn extract_field_validator_from_meta_list( field: &impl Field, validation_type: MetaListFieldValidation, validation: &syn::MetaList, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { match validation_type { MetaListFieldValidation::Enumerate => { - extract_generic_enumerate_validator(field, validation, custom_message, rename_map) + extract_generic_enumerate_validator(field, validation, message_format, rename_map) } MetaListFieldValidation::Custom => { - extract_generic_custom_validator(field, validation, custom_message, rename_map) + extract_generic_custom_validator(field, validation, message_format, rename_map) } } } diff --git a/serde_valid_derive/src/attribute/field_validate/meta/meta_name_value.rs b/serde_valid_derive/src/attribute/field_validate/meta/meta_name_value.rs index 163adfd..e15ee04 100644 --- a/serde_valid_derive/src/attribute/field_validate/meta/meta_name_value.rs +++ b/serde_valid_derive/src/attribute/field_validate/meta/meta_name_value.rs @@ -2,7 +2,7 @@ use crate::attribute::field_validate::array::{ extract_array_max_items_validator, extract_array_min_items_validator, }; use crate::attribute::field_validate::common::{ - get_lit, CustomMessageToken, MetaNameValueFieldValidation, + get_lit, MessageFormat, MetaNameValueFieldValidation, }; use crate::attribute::field_validate::numeric::{ extract_numeric_exclusive_maximum_validator, extract_numeric_exclusive_minimum_validator, @@ -24,23 +24,23 @@ pub fn extract_field_validator_from_meta_name_value( field: &impl Field, validation_type: MetaNameValueFieldValidation, validation: &syn::MetaNameValue, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { let validation_value = get_lit(&validation.value)?; match validation_type { MetaNameValueFieldValidation::Minimum => { - extract_numeric_minimum_validator(field, validation_value, custom_message, rename_map) + extract_numeric_minimum_validator(field, validation_value, message_format, rename_map) } MetaNameValueFieldValidation::Maximum => { - extract_numeric_maximum_validator(field, validation_value, custom_message, rename_map) + extract_numeric_maximum_validator(field, validation_value, message_format, rename_map) } MetaNameValueFieldValidation::ExclusiveMinimum => { extract_numeric_exclusive_minimum_validator( field, validation_value, - custom_message, + message_format, rename_map, ) } @@ -48,42 +48,42 @@ pub fn extract_field_validator_from_meta_name_value( extract_numeric_exclusive_maximum_validator( field, validation_value, - custom_message, + message_format, rename_map, ) } MetaNameValueFieldValidation::MinLength => { - extract_string_min_length_validator(field, validation_value, custom_message, rename_map) + extract_string_min_length_validator(field, validation_value, message_format, rename_map) } MetaNameValueFieldValidation::MaxLength => { - extract_string_max_length_validator(field, validation_value, custom_message, rename_map) + extract_string_max_length_validator(field, validation_value, message_format, rename_map) } MetaNameValueFieldValidation::MinItems => { - extract_array_min_items_validator(field, validation_value, custom_message, rename_map) + extract_array_min_items_validator(field, validation_value, message_format, rename_map) } MetaNameValueFieldValidation::MaxItems => { - extract_array_max_items_validator(field, validation_value, custom_message, rename_map) + extract_array_max_items_validator(field, validation_value, message_format, rename_map) } MetaNameValueFieldValidation::MinProperties => extract_object_min_properties_validator( field, validation_value, - custom_message, + message_format, rename_map, ), MetaNameValueFieldValidation::MaxProperties => extract_object_max_properties_validator( field, validation_value, - custom_message, + message_format, rename_map, ), MetaNameValueFieldValidation::MultipleOf => extract_numeric_multiple_of_validator( field, validation_value, - custom_message, + message_format, rename_map, ), MetaNameValueFieldValidation::Pattern => { - extract_string_pattern_validator(field, validation_value, custom_message, rename_map) + extract_string_pattern_validator(field, validation_value, message_format, rename_map) } } } diff --git a/serde_valid_derive/src/attribute/field_validate/meta/meta_path.rs b/serde_valid_derive/src/attribute/field_validate/meta/meta_path.rs index 4d2b5de..5de59cb 100644 --- a/serde_valid_derive/src/attribute/field_validate/meta/meta_path.rs +++ b/serde_valid_derive/src/attribute/field_validate/meta/meta_path.rs @@ -1,5 +1,5 @@ use crate::attribute::field_validate::array::extract_array_unique_items_validator; -use crate::attribute::field_validate::common::{CustomMessageToken, MetaPathFieldValidation}; +use crate::attribute::field_validate::common::{MessageFormat, MetaPathFieldValidation}; use crate::attribute::field_validate::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; @@ -8,13 +8,13 @@ pub fn extract_field_validator_from_meta_path( field: &impl Field, validation_type: MetaPathFieldValidation, _validation: &syn::Path, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { match validation_type { MetaPathFieldValidation::UniqueItems => Ok(extract_array_unique_items_validator( field, - custom_message, + message_format, rename_map, )), } diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs index 853c7b8..36d0760 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs @@ -1,4 +1,4 @@ -use crate::attribute::field_validate::common::{get_numeric, CustomMessageToken}; +use crate::attribute::field_validate::common::{get_numeric, MessageFormat}; use crate::attribute::field_validate::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; @@ -8,16 +8,16 @@ use quote::quote; pub fn extract_numeric_multiple_of_validator( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { - inner_extract_numeric_multiple_of_validator(field, validation_value, custom_message, rename_map) + inner_extract_numeric_multiple_of_validator(field, validation_value, message_format, rename_map) } fn inner_extract_numeric_multiple_of_validator( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { let field_name = field.name(); @@ -26,7 +26,6 @@ fn inner_extract_numeric_multiple_of_validator( let rename = rename_map.get(field_name).unwrap_or(&field_key); let errors = field.errors_variable(); let multiple_of = get_numeric(validation_value)?; - let custom_message = custom_message.into_token(); Ok(quote!( if let Err(__composited_error_params) = ::serde_valid::validation::ValidateCompositedMultipleOf::validate_composited_multiple_of( @@ -39,7 +38,7 @@ fn inner_extract_numeric_multiple_of_validator( #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); + .push(__composited_error_params.into_error_by(#message_format)); } )) } diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs index cb96081..4557d79 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs @@ -1,5 +1,5 @@ -use crate::attribute::field_validate::common::get_numeric; -use crate::attribute::field_validate::{common::CustomMessageToken, Validator}; +use crate::attribute::field_validate::common::{get_numeric, MessageFormat}; +use crate::attribute::field_validate::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; @@ -14,16 +14,16 @@ macro_rules! extract_numeric_range_validator{ pub fn []( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { - [](field, validation_value, custom_message, rename_map) + [](field, validation_value, message_format, rename_map) } fn []( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { let field_name = field.name(); @@ -32,7 +32,6 @@ macro_rules! extract_numeric_range_validator{ let rename = rename_map.get(field_name).unwrap_or(&field_key); let errors = field.errors_variable(); let [<$ErrorType:snake>] = get_numeric(validation_value)?; - let custom_message = custom_message.into_token(); Ok(quote!( if let Err(__composited_error_params) = ::serde_valid::validation::[]::[]( @@ -45,7 +44,7 @@ macro_rules! extract_numeric_range_validator{ #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); + .push(__composited_error_params.into_error_by(#message_format)); } )) } diff --git a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs index d9a16a3..946af8c 100644 --- a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs +++ b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs @@ -1,5 +1,5 @@ -use crate::attribute::field_validate::common::get_numeric; -use crate::attribute::field_validate::{common::CustomMessageToken, Validator}; +use crate::attribute::field_validate::common::{get_numeric, MessageFormat}; +use crate::attribute::field_validate::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; @@ -14,16 +14,16 @@ macro_rules! extract_object_size_validator { pub fn []( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { - [](field, validation_value, custom_message, rename_map) + [](field, validation_value, message_format, rename_map) } fn []( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { let field_name = field.name(); @@ -32,7 +32,6 @@ macro_rules! extract_object_size_validator { let rename = rename_map.get(field_name).unwrap_or(&field_key); let errors = field.errors_variable(); let [<$ErrorType:snake>] = get_numeric(validation_value)?; - let custom_message = custom_message.into_token(); Ok(quote!( if let Err(__composited_error_params) = ::serde_valid::validation::[]::[]( @@ -45,7 +44,7 @@ macro_rules! extract_object_size_validator { #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); + .push(__composited_error_params.into_error_by(#message_format)); } )) } diff --git a/serde_valid_derive/src/attribute/field_validate/string/length.rs b/serde_valid_derive/src/attribute/field_validate/string/length.rs index c9cfb05..b833f34 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/length.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/length.rs @@ -1,5 +1,5 @@ -use crate::attribute::field_validate::common::get_numeric; -use crate::attribute::field_validate::{common::CustomMessageToken, Validator}; +use crate::attribute::field_validate::common::{get_numeric, MessageFormat}; +use crate::attribute::field_validate::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; @@ -14,16 +14,16 @@ macro_rules! extract_string_length_validator{ pub fn []( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { - [](field, validation_value, custom_message, rename_map) + [](field, validation_value, message_format, rename_map) } fn []( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { let field_name = field.name(); @@ -32,7 +32,6 @@ macro_rules! extract_string_length_validator{ let rename = rename_map.get(field_name).unwrap_or(&field_key); let errors = field.errors_variable(); let [<$ErrorType:snake>] = get_numeric(validation_value)?; - let custom_message = custom_message.into_token(); Ok(quote!( if let Err(__composited_error_params) = ::serde_valid::validation::[]::[]( @@ -45,7 +44,7 @@ macro_rules! extract_string_length_validator{ #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); + .push(__composited_error_params.into_error_by(#message_format)); } )) } diff --git a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs index 07c36c9..2c0fc85 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs @@ -1,7 +1,5 @@ -use crate::attribute::field_validate::{ - common::{get_str, CustomMessageToken}, - Validator, -}; +use crate::attribute::field_validate::common::MessageFormat; +use crate::attribute::field_validate::{common::get_str, Validator}; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; @@ -10,16 +8,16 @@ use quote::quote; pub fn extract_string_pattern_validator( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { - inner_extract_string_pattern_validator(field, validation_value, custom_message, rename_map) + inner_extract_string_pattern_validator(field, validation_value, message_format, rename_map) } fn inner_extract_string_pattern_validator( field: &impl Field, validation_value: &syn::Lit, - custom_message: CustomMessageToken, + message_format: MessageFormat, rename_map: &RenameMap, ) -> Result { let field_name = field.name(); @@ -32,7 +30,6 @@ fn inner_extract_string_pattern_validator( &format!("{}_PATTERN", &field_ident).to_uppercase(), field_ident.span(), ); - let custom_message = custom_message.into_token(); Ok(quote!( static #pattern_ident : ::serde_valid::export::OnceCell<::regex::Regex> = ::serde_valid::export::OnceCell::new(); @@ -47,7 +44,7 @@ fn inner_extract_string_pattern_validator( #errors .entry(#rename) .or_default() - .push(__composited_error_params.into_error_by(#custom_message.unwrap_or_default())); + .push(__composited_error_params.into_error_by(#message_format)); } )) } diff --git a/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs b/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs index c554b1d..a13e817 100644 --- a/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs +++ b/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs @@ -1,11 +1,11 @@ -use quote::quote; - -use crate::attribute::field_validate::{CustomMessageToken, Validator}; +use crate::attribute::field_validate::MessageFormat; +use crate::attribute::field_validate::Validator; use crate::types::CommaSeparatedNestedMetas; +use quote::quote; pub fn extract_generic_struct_custom_validator( meta_list: &syn::MetaList, - _custom_message: CustomMessageToken, + _message_format: MessageFormat, ) -> Result { let mut errors = vec![]; diff --git a/serde_valid_derive/src/attribute/struct_validate/meta.rs b/serde_valid_derive/src/attribute/struct_validate/meta.rs index 5c370ca..ab0d19a 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta.rs @@ -2,7 +2,7 @@ mod meta_list; mod meta_name_value; mod meta_path; -use crate::attribute::field_validate::{extract_custom_message_tokens, CustomMessageToken}; +use crate::attribute::field_validate::{default_message_format, extract_custom_message_format}; use crate::attribute::field_validate::{ MetaListStructValidation, MetaNameValueStructValidation, MetaPathStructValidation, Validator, }; @@ -41,25 +41,26 @@ fn inner_extract_struct_validator( )] })?; - let custom_message = match nested.len() { + let message_format = match nested.len() { 0 => Err(vec![crate::Error::struct_validation_type_required( attribute, )])?, - 1 => CustomMessageToken::default(), - 2 => match extract_custom_message_tokens(&nested[1]) { - Ok(custom_message) => custom_message, + 1 => None, + 2 => match extract_custom_message_format(&nested[1]) { + Ok(custom_message) => Some(custom_message), Err(message_fn_errors) => { errors.extend(message_fn_errors); - CustomMessageToken::default() + None } }, _ => { for meta in nested.iter().skip(2) { errors.push(crate::Error::too_many_list_items(meta)); } - CustomMessageToken::default() + None } - }; + } + .unwrap_or_else(default_message_format); let meta = &nested[0]; let validation_path = match meta { @@ -76,18 +77,18 @@ fn inner_extract_struct_validator( meta, ) { (Ok(validation_type), _, _, syn::Meta::Path(validation)) => { - extract_struct_validator_from_meta_path(validation_type, validation, custom_message) + extract_struct_validator_from_meta_path(validation_type, validation, message_format) } (_, Ok(validation_type), _, syn::Meta::List(validation)) => { - extract_struct_validator_from_meta_list(validation_type, validation, custom_message) + extract_struct_validator_from_meta_list(validation_type, validation, message_format) } (_, _, Ok(validation_type), syn::Meta::NameValue(validation)) => { extract_struct_validator_from_meta_name_value( validation_type, validation, - custom_message, + message_format, ) } diff --git a/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs b/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs index fb6b441..a05e159 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs @@ -1,14 +1,14 @@ -use crate::attribute::field_validate::{CustomMessageToken, MetaListStructValidation, Validator}; +use crate::attribute::field_validate::{MessageFormat, MetaListStructValidation, Validator}; use crate::attribute::struct_validate::generic::extract_generic_struct_custom_validator; pub fn extract_struct_validator_from_meta_list( validation_type: MetaListStructValidation, validation: &syn::MetaList, - custom_message: CustomMessageToken, + message_format: MessageFormat, ) -> Result { match validation_type { MetaListStructValidation::Custom => { - extract_generic_struct_custom_validator(validation, custom_message) + extract_generic_struct_custom_validator(validation, message_format) } } } diff --git a/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs b/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs index 23926d0..9370f60 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs @@ -1,12 +1,10 @@ -use crate::attribute::field_validate::{ - CustomMessageToken, MetaNameValueStructValidation, Validator, -}; +use crate::attribute::field_validate::{MessageFormat, MetaNameValueStructValidation, Validator}; #[inline] pub fn extract_struct_validator_from_meta_name_value( validation_type: MetaNameValueStructValidation, _validation: &syn::MetaNameValue, - _custom_message: CustomMessageToken, + _message_format: MessageFormat, ) -> Result { match validation_type {} } diff --git a/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs b/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs index 2deba93..5c81035 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs @@ -1,10 +1,10 @@ -use crate::attribute::field_validate::{CustomMessageToken, MetaPathStructValidation, Validator}; +use crate::attribute::field_validate::{MessageFormat, MetaPathStructValidation, Validator}; #[inline] pub fn extract_struct_validator_from_meta_path( validation_type: MetaPathStructValidation, _validation: &syn::Path, - _custom_message: CustomMessageToken, + _message_format: MessageFormat, ) -> Result { match validation_type {} } From 67f298c008fc8aa6a5b5542d4f613151c3cbf69c Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Fri, 12 Jan 2024 00:21:51 +0900 Subject: [PATCH 13/25] move: common module. --- serde_valid_derive/src/attribute.rs | 145 ++++++++++++++++++ serde_valid_derive/src/attribute/common.rs | 2 + .../{field_validate => }/common/lit.rs | 0 .../common/message_format.rs | 4 +- .../src/attribute/field_validate.rs | 10 +- .../field_validate/array/length_items.rs | 5 +- .../field_validate/array/unique_items.rs | 3 +- .../src/attribute/field_validate/common.rs | 145 ------------------ .../src/attribute/field_validate/field.rs | 12 +- .../field_validate/generic/custom.rs | 4 +- .../field_validate/generic/enumerate.rs | 4 +- .../field_validate/generic/validate.rs | 2 +- .../src/attribute/field_validate/meta.rs | 5 +- .../field_validate/meta/meta_list.rs | 5 +- .../field_validate/meta/meta_name_value.rs | 7 +- .../field_validate/meta/meta_path.rs | 4 +- .../field_validate/numeric/multiple_of.rs | 5 +- .../attribute/field_validate/numeric/range.rs | 5 +- .../field_validate/object/size_properties.rs | 5 +- .../attribute/field_validate/string/length.rs | 5 +- .../field_validate/string/pattern.rs | 5 +- .../src/attribute/struct_validate.rs | 2 +- .../struct_validate/generic/custom.rs | 4 +- .../src/attribute/struct_validate/meta.rs | 11 +- .../struct_validate/meta/meta_list.rs | 7 +- .../struct_validate/meta/meta_name_value.rs | 4 +- .../struct_validate/meta/meta_path.rs | 4 +- serde_valid_derive/src/error.rs | 10 +- 28 files changed, 215 insertions(+), 209 deletions(-) create mode 100644 serde_valid_derive/src/attribute/common.rs rename serde_valid_derive/src/attribute/{field_validate => }/common/lit.rs (100%) rename serde_valid_derive/src/attribute/{field_validate => }/common/message_format.rs (97%) delete mode 100644 serde_valid_derive/src/attribute/field_validate/common.rs diff --git a/serde_valid_derive/src/attribute.rs b/serde_valid_derive/src/attribute.rs index 6a7121e..683a6c3 100644 --- a/serde_valid_derive/src/attribute.rs +++ b/serde_valid_derive/src/attribute.rs @@ -1,3 +1,148 @@ +use proc_macro2::TokenStream; + +pub mod common; pub mod field_validate; pub mod rule; pub mod struct_validate; + +pub type Validator = TokenStream; + +macro_rules! count { + () => (0usize); + ( $x:literal $($xs:literal)* ) => (1usize + count!($($xs)*)); +} + +macro_rules! enum_str { + (pub enum $name:ident {}) => { + pub enum $name { + } + + impl $name { + #[allow(dead_code)] + pub fn name(&self) -> &'static str { + unimplemented!() + } + + #[allow(dead_code)] + pub fn iter() -> std::array::IntoIter { + [].into_iter() + } + } + + impl std::str::FromStr for $name { + type Err = String; + + fn from_str(s: &str) -> Result { + Err(s.to_owned()) + } + } + }; + + (pub enum $name:ident { + $($variant:ident = $val:literal),*, + }) => { + pub enum $name { + $($variant,)* + } + + impl $name { + #[allow(dead_code)] + pub fn name(&self) -> &'static str { + match *self { + $($name::$variant => $val),* + } + } + + #[allow(dead_code)] + pub fn iter() -> std::array::IntoIter { + [ + $($name::$variant),* + ].into_iter() + } + } + + impl std::str::FromStr for $name { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + $($val => Ok($name::$variant) ),*, + _ => Err(s.to_owned()) + } + } + } + }; +} + +enum_str! { + pub enum MetaPathStructValidation { + } +} + +enum_str! { + pub enum MetaListStructValidation { + Custom = "custom", + } +} + +enum_str! { + pub enum MetaNameValueStructValidation { + } +} + +enum_str! { + pub enum MetaPathFieldValidation { + UniqueItems = "unique_items", + } +} + +enum_str! { + pub enum MetaListFieldValidation { + Enumerate = "enumerate", + Custom = "custom", + } +} + +enum_str! { + pub enum MetaNameValueFieldValidation { + Minimum = "minimum", + Maximum = "maximum", + ExclusiveMinimum = "exclusive_minimum", + ExclusiveMaximum = "exclusive_maximum", + MinLength = "min_length", + MaxLength = "max_length", + MinItems = "min_items", + MaxItems = "max_items", + MinProperties = "min_properties", + MaxProperties = "max_properties", + MultipleOf = "multiple_of", + Pattern = "pattern", + } +} + +enum_str! { + pub enum MetaPathCustomMessage { + } +} + +#[cfg(not(feature = "fluent"))] +enum_str! { + pub enum MetaListCustomMessage { + MessageFn = "message_fn", + } +} + +#[cfg(feature = "fluent")] +enum_str! { + pub enum MetaListCustomMessage { + MessageFn = "message_fn", + I18n = "i18n", + Fluent = "fluent", + } +} + +enum_str! { + pub enum MetaNameValueCustomMessage { + Message = "message", + } +} diff --git a/serde_valid_derive/src/attribute/common.rs b/serde_valid_derive/src/attribute/common.rs new file mode 100644 index 0000000..18c0db0 --- /dev/null +++ b/serde_valid_derive/src/attribute/common.rs @@ -0,0 +1,2 @@ +pub mod lit; +pub mod message_format; diff --git a/serde_valid_derive/src/attribute/field_validate/common/lit.rs b/serde_valid_derive/src/attribute/common/lit.rs similarity index 100% rename from serde_valid_derive/src/attribute/field_validate/common/lit.rs rename to serde_valid_derive/src/attribute/common/lit.rs diff --git a/serde_valid_derive/src/attribute/field_validate/common/message_format.rs b/serde_valid_derive/src/attribute/common/message_format.rs similarity index 97% rename from serde_valid_derive/src/attribute/field_validate/common/message_format.rs rename to serde_valid_derive/src/attribute/common/message_format.rs index 34a1b11..2cf98f1 100644 --- a/serde_valid_derive/src/attribute/field_validate/common/message_format.rs +++ b/serde_valid_derive/src/attribute/common/message_format.rs @@ -1,10 +1,10 @@ +use crate::attribute::{MetaListCustomMessage, MetaNameValueCustomMessage, MetaPathCustomMessage}; use crate::types::{CommaSeparatedNestedMetas, NestedMeta, SingleIdentPath}; use proc_macro2::TokenStream; use quote::quote; use std::str::FromStr; -use super::{get_str, MetaListCustomMessage, MetaNameValueCustomMessage, MetaPathCustomMessage}; - +use super::lit::get_str; pub type MessageFormat = TokenStream; pub fn default_message_format() -> MessageFormat { diff --git a/serde_valid_derive/src/attribute/field_validate.rs b/serde_valid_derive/src/attribute/field_validate.rs index 018a3f1..a1bfb9b 100644 --- a/serde_valid_derive/src/attribute/field_validate.rs +++ b/serde_valid_derive/src/attribute/field_validate.rs @@ -1,5 +1,4 @@ mod array; -mod common; mod field; mod generic; mod meta; @@ -7,12 +6,5 @@ mod numeric; mod object; mod string; -pub use common::{ - default_message_format, extract_custom_message_format, MessageFormat, MetaListCustomMessage, - MetaListFieldValidation, MetaListStructValidation, MetaNameValueCustomMessage, - MetaNameValueFieldValidation, MetaNameValueStructValidation, MetaPathCustomMessage, - MetaPathFieldValidation, MetaPathStructValidation, -}; - -pub use field::{FieldValidators, Validator}; +pub use field::FieldValidators; pub use meta::extract_field_validator; diff --git a/serde_valid_derive/src/attribute/field_validate/array/length_items.rs b/serde_valid_derive/src/attribute/field_validate/array/length_items.rs index b6ebea3..c4b2030 100644 --- a/serde_valid_derive/src/attribute/field_validate/array/length_items.rs +++ b/serde_valid_derive/src/attribute/field_validate/array/length_items.rs @@ -1,5 +1,6 @@ -use crate::attribute::field_validate::common::get_numeric; -use crate::attribute::field_validate::{common::MessageFormat, Validator}; +use crate::attribute::common::lit::get_numeric; +use crate::attribute::common::message_format::MessageFormat; +use crate::attribute::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; diff --git a/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs b/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs index 30e20b1..cbb3b5a 100644 --- a/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs +++ b/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs @@ -1,4 +1,5 @@ -use crate::attribute::field_validate::{common::MessageFormat, Validator}; +use crate::attribute::common::message_format::MessageFormat; +use crate::attribute::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; diff --git a/serde_valid_derive/src/attribute/field_validate/common.rs b/serde_valid_derive/src/attribute/field_validate/common.rs deleted file mode 100644 index 7e313ac..0000000 --- a/serde_valid_derive/src/attribute/field_validate/common.rs +++ /dev/null @@ -1,145 +0,0 @@ -mod lit; -mod message_format; - -pub use lit::{get_lit, get_numeric, get_str}; -pub use message_format::{default_message_format, extract_custom_message_format, MessageFormat}; - -macro_rules! count { - () => (0usize); - ( $x:literal $($xs:literal)* ) => (1usize + count!($($xs)*)); -} - -macro_rules! enum_str { - (pub enum $name:ident {}) => { - pub enum $name { - } - - impl $name { - #[allow(dead_code)] - pub fn name(&self) -> &'static str { - unimplemented!() - } - - #[allow(dead_code)] - pub fn iter() -> std::array::IntoIter { - [].into_iter() - } - } - - impl std::str::FromStr for $name { - type Err = String; - - fn from_str(s: &str) -> Result { - Err(s.to_owned()) - } - } - }; - - (pub enum $name:ident { - $($variant:ident = $val:literal),*, - }) => { - pub enum $name { - $($variant,)* - } - - impl $name { - #[allow(dead_code)] - pub fn name(&self) -> &'static str { - match *self { - $($name::$variant => $val),* - } - } - - #[allow(dead_code)] - pub fn iter() -> std::array::IntoIter { - [ - $($name::$variant),* - ].into_iter() - } - } - - impl std::str::FromStr for $name { - type Err = String; - - fn from_str(s: &str) -> Result { - match s { - $($val => Ok($name::$variant) ),*, - _ => Err(s.to_owned()) - } - } - } - }; -} - -enum_str! { - pub enum MetaPathStructValidation { - } -} - -enum_str! { - pub enum MetaListStructValidation { - Custom = "custom", - } -} - -enum_str! { - pub enum MetaNameValueStructValidation { - } -} - -enum_str! { - pub enum MetaPathFieldValidation { - UniqueItems = "unique_items", - } -} - -enum_str! { - pub enum MetaListFieldValidation { - Enumerate = "enumerate", - Custom = "custom", - } -} - -enum_str! { - pub enum MetaNameValueFieldValidation { - Minimum = "minimum", - Maximum = "maximum", - ExclusiveMinimum = "exclusive_minimum", - ExclusiveMaximum = "exclusive_maximum", - MinLength = "min_length", - MaxLength = "max_length", - MinItems = "min_items", - MaxItems = "max_items", - MinProperties = "min_properties", - MaxProperties = "max_properties", - MultipleOf = "multiple_of", - Pattern = "pattern", - } -} - -enum_str! { - pub enum MetaPathCustomMessage { - } -} - -#[cfg(not(feature = "fluent"))] -enum_str! { - pub enum MetaListCustomMessage { - MessageFn = "message_fn", - } -} - -#[cfg(feature = "fluent")] -enum_str! { - pub enum MetaListCustomMessage { - MessageFn = "message_fn", - I18n = "i18n", - Fluent = "fluent", - } -} - -enum_str! { - pub enum MetaNameValueCustomMessage { - Message = "message", - } -} diff --git a/serde_valid_derive/src/attribute/field_validate/field.rs b/serde_valid_derive/src/attribute/field_validate/field.rs index 2a0c008..ee845a5 100644 --- a/serde_valid_derive/src/attribute/field_validate/field.rs +++ b/serde_valid_derive/src/attribute/field_validate/field.rs @@ -1,11 +1,9 @@ +use crate::attribute::Validator; use crate::types::Field; -use proc_macro2::TokenStream; use quote::quote; use std::borrow::Cow; use std::iter::FromIterator; -pub type Validator = TokenStream; - pub struct FieldValidators<'a, F: Field + Clone + 'a> { field: Cow<'a, F>, validators: Vec, @@ -24,16 +22,16 @@ impl<'a, F: Field + Clone> FieldValidators<'a, F> { self.validators.is_empty() } - pub fn get_tokens(&self) -> Option { + pub fn get_tokens(&self) -> Option { if !self.validators.is_empty() { - let validators = TokenStream::from_iter(self.validators.clone()); + let validators = Validator::from_iter(self.validators.clone()); Some(quote! (#validators)) } else { None } } - pub fn get_field_variable_token(&self) -> TokenStream { + pub fn get_field_variable_token(&self) -> Validator { let field_ident = self.field.ident(); let field_getter = self.field.getter_token(); quote!( @@ -41,7 +39,7 @@ impl<'a, F: Field + Clone> FieldValidators<'a, F> { ) } - pub fn generate_tokens(&self) -> TokenStream { + pub fn generate_tokens(&self) -> Validator { let normal_tokens = self.get_tokens(); if normal_tokens.is_some() { diff --git a/serde_valid_derive/src/attribute/field_validate/generic/custom.rs b/serde_valid_derive/src/attribute/field_validate/generic/custom.rs index 3b42598..9d78567 100644 --- a/serde_valid_derive/src/attribute/field_validate/generic/custom.rs +++ b/serde_valid_derive/src/attribute/field_validate/generic/custom.rs @@ -1,5 +1,5 @@ -use crate::attribute::field_validate::common::MessageFormat; -use crate::attribute::field_validate::Validator; +use crate::attribute::common::message_format::MessageFormat; +use crate::attribute::Validator; use crate::serde::rename::RenameMap; use crate::types::{CommaSeparatedNestedMetas, Field, SingleIdentPath}; use proc_macro2::TokenStream; diff --git a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs index 1fd75c4..14271ce 100644 --- a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs +++ b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs @@ -1,5 +1,5 @@ -use crate::attribute::field_validate::common::MessageFormat; -use crate::attribute::field_validate::Validator; +use crate::attribute::common::message_format::MessageFormat; +use crate::attribute::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use quote::quote; diff --git a/serde_valid_derive/src/attribute/field_validate/generic/validate.rs b/serde_valid_derive/src/attribute/field_validate/generic/validate.rs index a1d1f6b..a74dded 100644 --- a/serde_valid_derive/src/attribute/field_validate/generic/validate.rs +++ b/serde_valid_derive/src/attribute/field_validate/generic/validate.rs @@ -1,4 +1,4 @@ -use crate::attribute::field_validate::Validator; +use crate::attribute::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use quote::quote; diff --git a/serde_valid_derive/src/attribute/field_validate/meta.rs b/serde_valid_derive/src/attribute/field_validate/meta.rs index 05ba581..a5c57d4 100644 --- a/serde_valid_derive/src/attribute/field_validate/meta.rs +++ b/serde_valid_derive/src/attribute/field_validate/meta.rs @@ -2,8 +2,8 @@ mod meta_list; mod meta_name_value; mod meta_path; -use crate::attribute::field_validate::common::extract_custom_message_format; -use crate::attribute::field_validate::{ +use crate::attribute::common::message_format::{extract_custom_message_format, default_message_format}; +use crate::attribute::{ MetaListFieldValidation, MetaNameValueFieldValidation, MetaPathFieldValidation, Validator, }; use crate::serde::rename::RenameMap; @@ -14,7 +14,6 @@ use meta_name_value::extract_field_validator_from_meta_name_value; use meta_path::extract_field_validator_from_meta_path; use std::str::FromStr; -use super::common::default_message_format; use super::generic::extract_generic_validate_validator; pub fn extract_field_validator( diff --git a/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs b/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs index c4e4c59..c8568a4 100644 --- a/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs +++ b/serde_valid_derive/src/attribute/field_validate/meta/meta_list.rs @@ -1,8 +1,9 @@ -use crate::attribute::field_validate::common::{MessageFormat, MetaListFieldValidation}; +use crate::attribute::common::message_format::MessageFormat; use crate::attribute::field_validate::generic::{ extract_generic_custom_validator, extract_generic_enumerate_validator, }; -use crate::attribute::field_validate::Validator; +use crate::attribute::MetaListFieldValidation; +use crate::attribute::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; diff --git a/serde_valid_derive/src/attribute/field_validate/meta/meta_name_value.rs b/serde_valid_derive/src/attribute/field_validate/meta/meta_name_value.rs index e15ee04..148fe2c 100644 --- a/serde_valid_derive/src/attribute/field_validate/meta/meta_name_value.rs +++ b/serde_valid_derive/src/attribute/field_validate/meta/meta_name_value.rs @@ -1,9 +1,8 @@ +use crate::attribute::common::lit::get_lit; +use crate::attribute::common::message_format::MessageFormat; use crate::attribute::field_validate::array::{ extract_array_max_items_validator, extract_array_min_items_validator, }; -use crate::attribute::field_validate::common::{ - get_lit, MessageFormat, MetaNameValueFieldValidation, -}; use crate::attribute::field_validate::numeric::{ extract_numeric_exclusive_maximum_validator, extract_numeric_exclusive_minimum_validator, extract_numeric_maximum_validator, extract_numeric_minimum_validator, @@ -16,7 +15,7 @@ use crate::attribute::field_validate::string::{ extract_string_max_length_validator, extract_string_min_length_validator, extract_string_pattern_validator, }; -use crate::attribute::field_validate::Validator; +use crate::attribute::{MetaNameValueFieldValidation, Validator}; use crate::serde::rename::RenameMap; use crate::types::Field; diff --git a/serde_valid_derive/src/attribute/field_validate/meta/meta_path.rs b/serde_valid_derive/src/attribute/field_validate/meta/meta_path.rs index 5de59cb..6caa170 100644 --- a/serde_valid_derive/src/attribute/field_validate/meta/meta_path.rs +++ b/serde_valid_derive/src/attribute/field_validate/meta/meta_path.rs @@ -1,6 +1,6 @@ +use crate::attribute::common::message_format::MessageFormat; use crate::attribute::field_validate::array::extract_array_unique_items_validator; -use crate::attribute::field_validate::common::{MessageFormat, MetaPathFieldValidation}; -use crate::attribute::field_validate::Validator; +use crate::attribute::{MetaPathFieldValidation, Validator}; use crate::serde::rename::RenameMap; use crate::types::Field; diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs index 36d0760..3567802 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs @@ -1,5 +1,6 @@ -use crate::attribute::field_validate::common::{get_numeric, MessageFormat}; -use crate::attribute::field_validate::Validator; +use crate::attribute::common::lit::get_numeric; +use crate::attribute::common::message_format::MessageFormat; +use crate::attribute::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs index 4557d79..e7c74a5 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs @@ -1,5 +1,6 @@ -use crate::attribute::field_validate::common::{get_numeric, MessageFormat}; -use crate::attribute::field_validate::Validator; +use crate::attribute::common::lit::get_numeric; +use crate::attribute::common::message_format::MessageFormat; +use crate::attribute::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; diff --git a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs index 946af8c..2fe82e9 100644 --- a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs +++ b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs @@ -1,5 +1,6 @@ -use crate::attribute::field_validate::common::{get_numeric, MessageFormat}; -use crate::attribute::field_validate::Validator; +use crate::attribute::common::lit::get_numeric; +use crate::attribute::common::message_format::MessageFormat; +use crate::attribute::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; diff --git a/serde_valid_derive/src/attribute/field_validate/string/length.rs b/serde_valid_derive/src/attribute/field_validate/string/length.rs index b833f34..e106450 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/length.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/length.rs @@ -1,5 +1,6 @@ -use crate::attribute::field_validate::common::{get_numeric, MessageFormat}; -use crate::attribute::field_validate::Validator; +use crate::attribute::common::lit::get_numeric; +use crate::attribute::common::message_format::MessageFormat; +use crate::attribute::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; diff --git a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs index 2c0fc85..6d9c363 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs @@ -1,5 +1,6 @@ -use crate::attribute::field_validate::common::MessageFormat; -use crate::attribute::field_validate::{common::get_str, Validator}; +use crate::attribute::common::lit::get_str; +use crate::attribute::common::message_format::MessageFormat; +use crate::attribute::Validator; use crate::serde::rename::RenameMap; use crate::types::Field; use proc_macro2::TokenStream; diff --git a/serde_valid_derive/src/attribute/struct_validate.rs b/serde_valid_derive/src/attribute/struct_validate.rs index c1fe0c8..c69eb43 100644 --- a/serde_valid_derive/src/attribute/struct_validate.rs +++ b/serde_valid_derive/src/attribute/struct_validate.rs @@ -1,7 +1,7 @@ mod generic; mod meta; -use crate::attribute::field_validate::Validator; +use crate::attribute::Validator; use self::meta::extract_struct_validator; diff --git a/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs b/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs index a13e817..40c7b7d 100644 --- a/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs +++ b/serde_valid_derive/src/attribute/struct_validate/generic/custom.rs @@ -1,5 +1,5 @@ -use crate::attribute::field_validate::MessageFormat; -use crate::attribute::field_validate::Validator; +use crate::attribute::common::message_format::MessageFormat; +use crate::attribute::Validator; use crate::types::CommaSeparatedNestedMetas; use quote::quote; diff --git a/serde_valid_derive/src/attribute/struct_validate/meta.rs b/serde_valid_derive/src/attribute/struct_validate/meta.rs index ab0d19a..59d3185 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta.rs @@ -2,11 +2,14 @@ mod meta_list; mod meta_name_value; mod meta_path; -use crate::attribute::field_validate::{default_message_format, extract_custom_message_format}; -use crate::attribute::field_validate::{ - MetaListStructValidation, MetaNameValueStructValidation, MetaPathStructValidation, Validator, +use crate::{ + attribute::{ + common::message_format::{default_message_format, extract_custom_message_format}, + MetaListStructValidation, MetaNameValueStructValidation, MetaPathStructValidation, + Validator, + }, + types::SingleIdentPath, }; -use crate::types::SingleIdentPath; use quote::quote; use std::str::FromStr; diff --git a/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs b/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs index a05e159..fe65d16 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta/meta_list.rs @@ -1,5 +1,8 @@ -use crate::attribute::field_validate::{MessageFormat, MetaListStructValidation, Validator}; -use crate::attribute::struct_validate::generic::extract_generic_struct_custom_validator; +use crate::attribute::{ + common::message_format::MessageFormat, + struct_validate::generic::extract_generic_struct_custom_validator, MetaListStructValidation, + Validator, +}; pub fn extract_struct_validator_from_meta_list( validation_type: MetaListStructValidation, diff --git a/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs b/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs index 9370f60..2dec887 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta/meta_name_value.rs @@ -1,4 +1,6 @@ -use crate::attribute::field_validate::{MessageFormat, MetaNameValueStructValidation, Validator}; +use crate::attribute::{ + common::message_format::MessageFormat, MetaNameValueStructValidation, Validator, +}; #[inline] pub fn extract_struct_validator_from_meta_name_value( diff --git a/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs b/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs index 5c81035..32ee315 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta/meta_path.rs @@ -1,4 +1,6 @@ -use crate::attribute::field_validate::{MessageFormat, MetaPathStructValidation, Validator}; +use crate::attribute::{ + common::message_format::MessageFormat, MetaPathStructValidation, Validator, +}; #[inline] pub fn extract_struct_validator_from_meta_path( diff --git a/serde_valid_derive/src/error.rs b/serde_valid_derive/src/error.rs index 85922b1..ce2995d 100644 --- a/serde_valid_derive/src/error.rs +++ b/serde_valid_derive/src/error.rs @@ -1,14 +1,12 @@ -use crate::attribute::field_validate::{ - MetaListFieldValidation, MetaListStructValidation, MetaNameValueCustomMessage, - MetaNameValueFieldValidation, MetaNameValueStructValidation, MetaPathCustomMessage, - MetaPathFieldValidation, MetaPathStructValidation, +use crate::attribute::{ + MetaListCustomMessage, MetaListFieldValidation, MetaListStructValidation, + MetaNameValueCustomMessage, MetaNameValueFieldValidation, MetaNameValueStructValidation, + MetaPathCustomMessage, MetaPathFieldValidation, MetaPathStructValidation, }; use proc_macro2::TokenStream; use quote::{quote, ToTokens}; use syn::spanned::Spanned; -use crate::attribute::field_validate::MetaListCustomMessage; - pub fn object_errors_tokens() -> TokenStream { quote!(::serde_valid::validation::Errors::Object( ::serde_valid::validation::ObjectErrors::new( From aa1161b165d78bf8d97aa0b16f9e30bdbad5191d Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Fri, 12 Jan 2024 00:22:52 +0900 Subject: [PATCH 14/25] update: crate version. --- serde_valid_derive/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serde_valid_derive/Cargo.toml b/serde_valid_derive/Cargo.toml index 4cf1471..95a4654 100644 --- a/serde_valid_derive/Cargo.toml +++ b/serde_valid_derive/Cargo.toml @@ -20,7 +20,7 @@ paste = { workspace = true } proc-macro-error = "^1.0" proc-macro2 = "^1.0" quote = "^1.0" -strsim = "^0.10" +strsim = "0.11.0" syn = { version = "^2.0", features = ["extra-traits", "full"] } [features] From 8b410751be8db4c06910c973bf364a9c8455f4a4 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Fri, 12 Jan 2024 00:27:56 +0900 Subject: [PATCH 15/25] feat: json is crate feature. --- serde_valid/Cargo.toml | 5 +++-- serde_valid/src/features.rs | 6 ++++++ serde_valid/src/{ => features}/json.rs | 0 serde_valid/src/{ => features}/json/from_json_reader.rs | 0 serde_valid/src/{ => features}/json/from_json_slice.rs | 0 serde_valid/src/{ => features}/json/from_json_str.rs | 0 serde_valid/src/{ => features}/json/from_json_value.rs | 0 serde_valid/src/{ => features}/json/to_json_string.rs | 0 serde_valid/src/{ => features}/json/to_json_value.rs | 0 serde_valid/src/{ => features}/json/to_json_writer.rs | 0 serde_valid/src/lib.rs | 7 ++++++- 11 files changed, 15 insertions(+), 3 deletions(-) rename serde_valid/src/{ => features}/json.rs (100%) rename serde_valid/src/{ => features}/json/from_json_reader.rs (100%) rename serde_valid/src/{ => features}/json/from_json_slice.rs (100%) rename serde_valid/src/{ => features}/json/from_json_str.rs (100%) rename serde_valid/src/{ => features}/json/from_json_value.rs (100%) rename serde_valid/src/{ => features}/json/to_json_string.rs (100%) rename serde_valid/src/{ => features}/json/to_json_value.rs (100%) rename serde_valid/src/{ => features}/json/to_json_writer.rs (100%) diff --git a/serde_valid/Cargo.toml b/serde_valid/Cargo.toml index a4a3f3f..c407964 100644 --- a/serde_valid/Cargo.toml +++ b/serde_valid/Cargo.toml @@ -21,7 +21,7 @@ once_cell = "^1.7" paste = { workspace = true } regex = { workspace = true } serde = { workspace = true, features = ["derive"] } -serde_json = { workspace = true } +serde_json = { workspace = true, optional = true } serde_toml = { package = "toml", version = "^0.8", optional = true } serde_valid_derive = { version = "0.16.3", path = "../serde_valid_derive" } serde_valid_literal = { version = "0.16.3", path = "../serde_valid_literal" } @@ -33,7 +33,8 @@ unicode-segmentation = "^1.7" unic-langid = "0.9.1" [features] -default = ["i128"] +default = ["i128", "json"] +json = ["serde_json"] toml = ["serde_toml"] yaml = ["serde_yaml"] i128 = ["num-traits/i128", "indexmap/std", "serde_valid_literal/i128"] diff --git a/serde_valid/src/features.rs b/serde_valid/src/features.rs index 6cd5fdf..9039e3c 100644 --- a/serde_valid/src/features.rs +++ b/serde_valid/src/features.rs @@ -1,8 +1,14 @@ #[cfg(feature = "flatten")] pub mod flatten; + #[cfg(feature = "fluent")] pub mod fluent; + +#[cfg(feature = "json")] +pub mod json; + #[cfg(feature = "toml")] pub mod toml; + #[cfg(feature = "yaml")] pub mod yaml; diff --git a/serde_valid/src/json.rs b/serde_valid/src/features/json.rs similarity index 100% rename from serde_valid/src/json.rs rename to serde_valid/src/features/json.rs diff --git a/serde_valid/src/json/from_json_reader.rs b/serde_valid/src/features/json/from_json_reader.rs similarity index 100% rename from serde_valid/src/json/from_json_reader.rs rename to serde_valid/src/features/json/from_json_reader.rs diff --git a/serde_valid/src/json/from_json_slice.rs b/serde_valid/src/features/json/from_json_slice.rs similarity index 100% rename from serde_valid/src/json/from_json_slice.rs rename to serde_valid/src/features/json/from_json_slice.rs diff --git a/serde_valid/src/json/from_json_str.rs b/serde_valid/src/features/json/from_json_str.rs similarity index 100% rename from serde_valid/src/json/from_json_str.rs rename to serde_valid/src/features/json/from_json_str.rs diff --git a/serde_valid/src/json/from_json_value.rs b/serde_valid/src/features/json/from_json_value.rs similarity index 100% rename from serde_valid/src/json/from_json_value.rs rename to serde_valid/src/features/json/from_json_value.rs diff --git a/serde_valid/src/json/to_json_string.rs b/serde_valid/src/features/json/to_json_string.rs similarity index 100% rename from serde_valid/src/json/to_json_string.rs rename to serde_valid/src/features/json/to_json_string.rs diff --git a/serde_valid/src/json/to_json_value.rs b/serde_valid/src/features/json/to_json_value.rs similarity index 100% rename from serde_valid/src/json/to_json_value.rs rename to serde_valid/src/features/json/to_json_value.rs diff --git a/serde_valid/src/json/to_json_writer.rs b/serde_valid/src/features/json/to_json_writer.rs similarity index 100% rename from serde_valid/src/json/to_json_writer.rs rename to serde_valid/src/features/json/to_json_writer.rs diff --git a/serde_valid/src/lib.rs b/serde_valid/src/lib.rs index 95ada8e..d21fb91 100644 --- a/serde_valid/src/lib.rs +++ b/serde_valid/src/lib.rs @@ -540,7 +540,6 @@ pub mod error; mod features; -pub mod json; mod traits; pub mod validation; @@ -562,10 +561,16 @@ pub use validation::{ #[cfg(feature = "flatten")] pub use features::flatten; + #[cfg(feature = "fluent")] pub use features::fluent; + +#[cfg(feature = "json")] +pub use features::json; + #[cfg(feature = "toml")] pub use features::toml; + #[cfg(feature = "yaml")] pub use features::yaml; From 1b3800f376aa31fda98d4fba916a9250ebd65c90 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Fri, 12 Jan 2024 00:31:35 +0900 Subject: [PATCH 16/25] feat: add default. --- serde_valid/src/validation/error/format.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/serde_valid/src/validation/error/format.rs b/serde_valid/src/validation/error/format.rs index c530682..301fe54 100644 --- a/serde_valid/src/validation/error/format.rs +++ b/serde_valid/src/validation/error/format.rs @@ -1,5 +1,6 @@ -#[derive(Clone)] +#[derive(Debug, Clone, Default)] pub enum Format { + #[default] Default, Message(String), MessageFn(fn(&E) -> String), From 209cd029474a8edce3ca96f4d38aba5a28e00669 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Fri, 12 Jan 2024 00:43:11 +0900 Subject: [PATCH 17/25] feat: remove unuse DefaultFormat trait. --- serde_valid/src/features/fluent/message.rs | 9 --------- serde_valid/src/validation/error/format.rs | 5 +---- serde_valid/src/validation/error/into_error.rs | 7 +------ serde_valid/src/validation/error/message.rs | 11 +---------- 4 files changed, 3 insertions(+), 29 deletions(-) diff --git a/serde_valid/src/features/fluent/message.rs b/serde_valid/src/features/fluent/message.rs index 2723aea..be5ea93 100644 --- a/serde_valid/src/features/fluent/message.rs +++ b/serde_valid/src/features/fluent/message.rs @@ -1,7 +1,5 @@ use fluent_0::FluentValue; -use crate::validation::error::DefaultFormat; - #[derive(Debug, Clone)] pub struct Message { pub id: &'static str, @@ -13,10 +11,3 @@ impl std::fmt::Display for Message { self.id.fmt(f) } } - -impl DefaultFormat for Message { - #[inline] - fn default_format(&self) -> String { - self.id.to_string() - } -} diff --git a/serde_valid/src/validation/error/format.rs b/serde_valid/src/validation/error/format.rs index 301fe54..53a8825 100644 --- a/serde_valid/src/validation/error/format.rs +++ b/serde_valid/src/validation/error/format.rs @@ -9,10 +9,7 @@ pub enum Format { } impl Format { - pub fn into_message(self, error: E) -> crate::validation::error::Message - where - E: DefaultFormat, - { + pub fn into_message(self, error: E) -> crate::validation::error::Message { crate::validation::error::Message::new(error, self) } } diff --git a/serde_valid/src/validation/error/into_error.rs b/serde_valid/src/validation/error/into_error.rs index b149a2b..941a889 100644 --- a/serde_valid/src/validation/error/into_error.rs +++ b/serde_valid/src/validation/error/into_error.rs @@ -1,9 +1,4 @@ -use crate::validation::error::DefaultFormat; - -pub trait IntoError: Sized -where - E: DefaultFormat, -{ +pub trait IntoError: Sized { fn into_error(self) -> crate::validation::Error { self.into_error_by(crate::validation::error::Format::Default) } diff --git a/serde_valid/src/validation/error/message.rs b/serde_valid/src/validation/error/message.rs index 8aaa88d..0a12154 100644 --- a/serde_valid/src/validation/error/message.rs +++ b/serde_valid/src/validation/error/message.rs @@ -1,6 +1,6 @@ use super::{DefaultFormat, Format}; -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct Message { error: E, format: Format, @@ -20,15 +20,6 @@ impl Message { } } -impl std::fmt::Debug for Message -where - E: std::fmt::Debug, -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Message {{ error: {:?} }}", &self.error) - } -} - impl std::fmt::Display for Message where E: DefaultFormat, From 28289ff378ed6146c4106b355cf7ea126ba70431 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Fri, 12 Jan 2024 00:47:52 +0900 Subject: [PATCH 18/25] fix: format. --- serde_valid_derive/src/attribute/field_validate/meta.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/serde_valid_derive/src/attribute/field_validate/meta.rs b/serde_valid_derive/src/attribute/field_validate/meta.rs index a5c57d4..b06eca8 100644 --- a/serde_valid_derive/src/attribute/field_validate/meta.rs +++ b/serde_valid_derive/src/attribute/field_validate/meta.rs @@ -2,7 +2,9 @@ mod meta_list; mod meta_name_value; mod meta_path; -use crate::attribute::common::message_format::{extract_custom_message_format, default_message_format}; +use crate::attribute::common::message_format::{ + default_message_format, extract_custom_message_format, +}; use crate::attribute::{ MetaListFieldValidation, MetaNameValueFieldValidation, MetaPathFieldValidation, Validator, }; From b84b8716e5828714d2ec79f97d7e0e96029a15d5 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Fri, 12 Jan 2024 09:40:30 +0900 Subject: [PATCH 19/25] chore: rename arg name. --- serde_valid/src/validation/composited.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/serde_valid/src/validation/composited.rs b/serde_valid/src/validation/composited.rs index a092705..f50712b 100644 --- a/serde_valid/src/validation/composited.rs +++ b/serde_valid/src/validation/composited.rs @@ -32,10 +32,10 @@ macro_rules! impl_into_error { ($ErrorType:ident) => { paste::paste! { impl IntoError<[<$ErrorType Error>]> for Composited<[<$ErrorType Error>]> { - fn into_error_by(self, custom: crate::validation::error::Format<[<$ErrorType Error>]>) -> crate::validation::error::Error { + fn into_error_by(self, format: crate::validation::error::Format<[<$ErrorType Error>]>) -> crate::validation::error::Error { match self { Composited::Single(single) => { - crate::validation::error::Error::$ErrorType(custom.into_message(single)) + crate::validation::error::Error::$ErrorType(format.into_message(single)) }, Composited::Array(array) =>{ crate::validation::error::Error::Items(crate::validation::error::ArrayErrors::new( @@ -43,7 +43,7 @@ macro_rules! impl_into_error { array .into_iter() .map(|(index, params)| { - (index, crate::validation::Errors::NewType(vec![params.into_error_by(custom.clone())])) + (index, crate::validation::Errors::NewType(vec![params.into_error_by(format.clone())])) }) .collect::>(), ))}, From 454b4067d7b26abfe255ca0c0a47968728f1ae94 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Fri, 12 Jan 2024 21:56:19 +0900 Subject: [PATCH 20/25] chore: merge test file. --- serde_valid/tests/custom_test.rs | 81 ++++++++++++++++++++++++ serde_valid/tests/struct_custom_test.rs | 82 ------------------------- 2 files changed, 81 insertions(+), 82 deletions(-) delete mode 100644 serde_valid/tests/struct_custom_test.rs diff --git a/serde_valid/tests/custom_test.rs b/serde_valid/tests/custom_test.rs index 9b7313c..300b725 100644 --- a/serde_valid/tests/custom_test.rs +++ b/serde_valid/tests/custom_test.rs @@ -111,3 +111,84 @@ fn custom_validation_error() { .to_string() ); } + +#[test] +fn named_struct_custom_is_ok() { + fn sample_struct_validation(_val: &TestStruct) -> Result<(), serde_valid::validation::Error> { + Ok(()) + } + + #[derive(Validate)] + #[validate(custom(sample_struct_validation))] + struct TestStruct { + val: i32, + } + + let s = TestStruct { val: 5 }; + assert_eq!(s.val, 5); + assert!(s.validate().is_ok()); +} + +#[test] +fn named_struct_custom_closure_is_ok() { + fn sample_struct_validation(_val: i32) -> Result<(), serde_valid::validation::Error> { + Ok(()) + } + + #[derive(Validate)] + #[validate(custom(|s| sample_struct_validation(s.val)))] + struct TestStruct { + val: i32, + } + + let s = TestStruct { val: 5 }; + assert_eq!(s.val, 5); + assert!(s.validate().is_ok()); +} + +#[test] +fn unnamed_struct_custom_is_ok() { + fn sample_struct_validation(_val: &TestStruct) -> Result<(), serde_valid::validation::Error> { + Ok(()) + } + + #[derive(Validate)] + #[validate(custom(sample_struct_validation))] + struct TestStruct(i32); + + let s = TestStruct(5); + assert_eq!(s.0, 5); + assert!(s.validate().is_ok()); +} + +#[test] +fn unnamed_struct_custom_closure_is_ok() { + fn sample_struct_validation(_val: i32) -> Result<(), serde_valid::validation::Error> { + Ok(()) + } + + #[derive(Validate)] + #[validate(custom(|s| sample_struct_validation(s.0)))] + struct TestStruct(i32); + + let s = TestStruct(5); + assert_eq!(s.0, 5); + assert!(s.validate().is_ok()); +} + +#[test] +fn unnamed_struct_custom_closure_is_err() { + fn sample_struct_validation(_val: i32) -> Result<(), serde_valid::validation::Error> { + Err(serde_valid::validation::Error::Custom( + "Struct Validation Error.".to_owned(), + )) + } + + #[derive(Validate)] + #[validate(custom(|s| sample_struct_validation(s.0)))] + struct TestStruct(i32); + + let s = TestStruct(5); + assert_eq!(s.0, 5); + assert!(s.validate().is_err()); +} diff --git a/serde_valid/tests/struct_custom_test.rs b/serde_valid/tests/struct_custom_test.rs deleted file mode 100644 index e99ff29..0000000 --- a/serde_valid/tests/struct_custom_test.rs +++ /dev/null @@ -1,82 +0,0 @@ -use serde_valid::Validate; - -#[test] -fn named_struct_custom_is_ok() { - fn sample_struct_validation(_val: &TestStruct) -> Result<(), serde_valid::validation::Error> { - Ok(()) - } - - #[derive(Validate)] - #[validate(custom(sample_struct_validation))] - struct TestStruct { - val: i32, - } - - let s = TestStruct { val: 5 }; - assert_eq!(s.val, 5); - assert!(s.validate().is_ok()); -} - -#[test] -fn named_struct_custom_closure_is_ok() { - fn sample_struct_validation(_val: i32) -> Result<(), serde_valid::validation::Error> { - Ok(()) - } - - #[derive(Validate)] - #[validate(custom(|s| sample_struct_validation(s.val)))] - struct TestStruct { - val: i32, - } - - let s = TestStruct { val: 5 }; - assert_eq!(s.val, 5); - assert!(s.validate().is_ok()); -} - -#[test] -fn unnamed_struct_custom_is_ok() { - fn sample_struct_validation(_val: &TestStruct) -> Result<(), serde_valid::validation::Error> { - Ok(()) - } - - #[derive(Validate)] - #[validate(custom(sample_struct_validation))] - struct TestStruct(i32); - - let s = TestStruct(5); - assert_eq!(s.0, 5); - assert!(s.validate().is_ok()); -} - -#[test] -fn unnamed_struct_custom_closure_is_ok() { - fn sample_struct_validation(_val: i32) -> Result<(), serde_valid::validation::Error> { - Ok(()) - } - - #[derive(Validate)] - #[validate(custom(|s| sample_struct_validation(s.0)))] - struct TestStruct(i32); - - let s = TestStruct(5); - assert_eq!(s.0, 5); - assert!(s.validate().is_ok()); -} - -#[test] -fn unnamed_struct_custom_closure_is_err() { - fn sample_struct_validation(_val: i32) -> Result<(), serde_valid::validation::Error> { - Err(serde_valid::validation::Error::Custom( - "Struct Validation Error.".to_owned(), - )) - } - - #[derive(Validate)] - #[validate(custom(|s| sample_struct_validation(s.0)))] - struct TestStruct(i32); - - let s = TestStruct(5); - assert_eq!(s.0, 5); - assert!(s.validate().is_err()); -} From 08839c4d8cc77cbb7c677b64241ddbff9d6130b9 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Fri, 12 Jan 2024 21:56:39 +0900 Subject: [PATCH 21/25] chore: add error handling. --- .../src/attribute/field_validate/meta.rs | 11 ++++++++++- .../src/attribute/struct_validate/meta.rs | 11 ++++++++++- serde_valid_derive/src/error.rs | 7 +++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/serde_valid_derive/src/attribute/field_validate/meta.rs b/serde_valid_derive/src/attribute/field_validate/meta.rs index b06eca8..8725577 100644 --- a/serde_valid_derive/src/attribute/field_validate/meta.rs +++ b/serde_valid_derive/src/attribute/field_validate/meta.rs @@ -55,7 +55,16 @@ fn inner_extract_field_validator( )])?, 1 => None, 2 => match extract_custom_message_format(&nested[1]) { - Ok(custom_message) => Some(custom_message), + Ok(custom_message) => { + if nested[0].path().is_ident("custom") { + errors.push(crate::Error::validate_custom_not_support_custom_message( + &nested[1], + )); + None + } else { + Some(custom_message) + } + } Err(message_fn_errors) => { errors.extend(message_fn_errors); None diff --git a/serde_valid_derive/src/attribute/struct_validate/meta.rs b/serde_valid_derive/src/attribute/struct_validate/meta.rs index 59d3185..cf0b396 100644 --- a/serde_valid_derive/src/attribute/struct_validate/meta.rs +++ b/serde_valid_derive/src/attribute/struct_validate/meta.rs @@ -50,7 +50,16 @@ fn inner_extract_struct_validator( )])?, 1 => None, 2 => match extract_custom_message_format(&nested[1]) { - Ok(custom_message) => Some(custom_message), + Ok(custom_message) => { + if nested[0].path().is_ident("custom") { + errors.push(crate::Error::validate_custom_not_support_custom_message( + &nested[1], + )); + None + } else { + Some(custom_message) + } + } Err(message_fn_errors) => { errors.extend(message_fn_errors); None diff --git a/serde_valid_derive/src/error.rs b/serde_valid_derive/src/error.rs index ce2995d..bc3dca6 100644 --- a/serde_valid_derive/src/error.rs +++ b/serde_valid_derive/src/error.rs @@ -471,6 +471,13 @@ impl Error { pub fn to_compile_error(&self) -> TokenStream { self.0.to_compile_error() } + + pub fn validate_custom_not_support_custom_message(meta: &syn::Meta) -> Self { + Self::new( + meta.span(), + "#[validate(custon(...), ???)] does not support custom error message.", + ) + } } fn did_you_mean<'a, T, I>(unknown: &'a str, candidates: I) -> Option> From fd122d33b5169ff83e550baa4d208b73bc85bc4a Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Sat, 13 Jan 2024 11:33:45 +0900 Subject: [PATCH 22/25] fix: fluent features. --- serde_valid/src/error.rs | 7 +- serde_valid/src/features/fluent.rs | 5 + serde_valid/src/features/fluent/error.rs | 9 + serde_valid/src/features/fluent/localize.rs | 454 +++++++++--------- .../src/features/fluent/try_localize.rs | 299 ++++++++++++ serde_valid/src/lib.rs | 5 + serde_valid/src/validation/error/message.rs | 23 +- 7 files changed, 567 insertions(+), 235 deletions(-) create mode 100644 serde_valid/src/features/fluent/error.rs create mode 100644 serde_valid/src/features/fluent/try_localize.rs diff --git a/serde_valid/src/error.rs b/serde_valid/src/error.rs index 7b74154..5849283 100644 --- a/serde_valid/src/error.rs +++ b/serde_valid/src/error.rs @@ -115,11 +115,10 @@ macro_rules! struct_error_params { ( #[derive(Debug, Clone)] #[default_format=$default_format:literal] - pub struct $Error:ident { - } + pub struct $Error:ident; ) => { #[derive(Debug, Clone)] - pub struct $Error {} + pub struct $Error; impl DefaultFormat for $Error { #[inline] @@ -216,7 +215,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] #[default_format = "The items must be unique."] - pub struct UniqueItemsError {} + pub struct UniqueItemsError; ); // Object diff --git a/serde_valid/src/features/fluent.rs b/serde_valid/src/features/fluent.rs index b35172d..2434835 100644 --- a/serde_valid/src/features/fluent.rs +++ b/serde_valid/src/features/fluent.rs @@ -1,4 +1,9 @@ +mod error; mod localize; mod message; +mod try_localize; +pub use error::LocalizedError; +pub use localize::Localize; pub use message::Message; +pub use try_localize::TryLocalize; diff --git a/serde_valid/src/features/fluent/error.rs b/serde_valid/src/features/fluent/error.rs new file mode 100644 index 0000000..1d48386 --- /dev/null +++ b/serde_valid/src/features/fluent/error.rs @@ -0,0 +1,9 @@ +use crate::validation::{ArrayErrors, ObjectErrors}; + +#[derive(Debug, Clone, serde::Serialize)] +#[serde(untagged)] +pub enum LocalizedError { + String(String), + Items(ArrayErrors), + Properties(ObjectErrors), +} diff --git a/serde_valid/src/features/fluent/localize.rs b/serde_valid/src/features/fluent/localize.rs index 8abb53a..5355f94 100644 --- a/serde_valid/src/features/fluent/localize.rs +++ b/serde_valid/src/features/fluent/localize.rs @@ -1,224 +1,230 @@ -// use fluent_0::{FluentArgs, FluentBundle, FluentError, FluentResource}; - -// use crate::validation::error::{ -// ArrayErrors, DefaultFormat, Errors, ItemErrorsMap, ObjectErrors, PropertyErrorsMap, VecErrors, -// }; - -// pub trait Localize { -// type Target; - -// fn localize(self, bundle: &FluentBundle) -> Self::Target; -// } - -// impl Localize for Errors { -// type Target = Errors; - -// fn localize(self, bundle: &FluentBundle) -> Self::Target { -// match self { -// Errors::Array(array) => Errors::Array(array.localize(bundle)), -// Errors::Object(object) => Errors::Object(object.localize(bundle)), -// Errors::NewType(newtype) => Errors::NewType(newtype.localize(bundle)), -// } -// } -// } - -// impl Localize for ArrayErrors { -// type Target = ArrayErrors; - -// fn localize(self, bundle: &FluentBundle) -> Self::Target { -// ArrayErrors { -// errors: self.errors.localize(bundle), -// items: self.items.localize(bundle), -// } -// } -// } - -// impl Localize for ObjectErrors { -// type Target = ObjectErrors; - -// fn localize(self, bundle: &FluentBundle) -> Self::Target { -// ObjectErrors { -// errors: self.errors.localize(bundle), -// properties: self.properties.localize(bundle), -// } -// } -// } - -// impl Localize for VecErrors { -// type Target = VecErrors; - -// fn localize(self, bundle: &FluentBundle) -> Self::Target { -// self.into_iter() -// .map(|error| error.localize(bundle)) -// .collect() -// } -// } - -// impl Localize for ItemErrorsMap { -// type Target = ItemErrorsMap; - -// fn localize(self, bundle: &FluentBundle) -> Self::Target { -// self.into_iter() -// .map(|(index, error)| (index, error.localize(bundle))) -// .collect::() -// } -// } - -// impl Localize for PropertyErrorsMap { -// type Target = PropertyErrorsMap; - -// fn localize(self, bundle: &FluentBundle) -> Self::Target { -// self.into_iter() -// .map(|(index, error)| (index, error.localize(bundle))) -// .collect::() -// } -// } - -// impl Localize for crate::validation::Error { -// type Target = String; - -// fn localize(self, bundle: &FluentBundle) -> Self::Target { -// match self { -// Self::Minimum(message) => localize_or_default(&message, bundle), -// Self::Maximum(message) => localize_or_default(&message, bundle), -// Self::ExclusiveMinimum(message) => localize_or_default(&message, bundle), -// Self::ExclusiveMaximum(message) => localize_or_default(&message, bundle), -// Self::MultipleOf(message) => localize_or_default(&message, bundle), -// Self::MinLength(message) => localize_or_default(&message, bundle), -// Self::MaxLength(message) => localize_or_default(&message, bundle), -// Self::Pattern(message) => localize_or_default(&message, bundle), -// Self::MinItems(message) => localize_or_default(&message, bundle), -// Self::MaxItems(message) => localize_or_default(&message, bundle), -// Self::UniqueItems(message) => localize_or_default(&message, bundle), -// Self::MinProperties(message) => localize_or_default(&message, bundle), -// Self::MaxProperties(message) => localize_or_default(&message, bundle), -// Self::Enumerate(message) => localize_or_default(&message, bundle), -// Self::Custom(message) => message, -// Self::Items(message) => format!("{message}"), -// Self::Properties(message) => format!("{message}"), -// Self::Fluent(message) => localize(&message, bundle), -// } -// } -// } - -// fn try_localize( -// message: &crate::validation::error::Message, -// bundle: &FluentBundle, -// ) -> Result, Vec> { -// if let Some(msg) = bundle.get_message(message.id) { -// if let Some(pattern) = msg.value() { -// let mut errors = vec![]; -// let args = FluentArgs::from_iter(message.args.to_owned()); -// let value = bundle -// .format_pattern(pattern, Some(&args), &mut errors) -// .to_string(); - -// if !errors.is_empty() { -// return Ok(Some(value)); -// } else { -// return Err(errors); -// } -// } -// } - -// Ok(None) -// } - -// fn localize( -// message: &crate::validation::error::Message, -// bundle: &FluentBundle, -// ) -> Option { -// try_localize(message, bundle).unwrap_or_else(|_| Some(message.to_string())) -// } - -// fn try_localize_or_default( -// message: &crate::validation::error::Message, -// bundle: &FluentBundle, -// ) -> Result> { -// if let Some(fluent_message) = message.fluent_message() { -// if let Some(value) = try_localize(fluent_message, bundle)? { -// return Ok(value); -// } -// } - -// Ok(format!("{message}")) -// } - -// fn localize_or_default( -// message: &crate::validation::error::Message, -// bundle: &FluentBundle, -// ) -> String { -// try_localize_or_default(message, bundle).unwrap_or_else(|_| message.to_string()) -// } - -// #[cfg(test)] -// mod test { -// use crate::{fluent::Message, validation::error::Format}; - -// use super::*; -// use fluent_0::{FluentResource, FluentValue}; -// use serde_valid_literal::Number; -// use unic_langid::LanguageIdentifier; - -// #[test] -// fn try_localize_without_args() { -// let ftl_string = "hello-world = Hello, world!".to_string(); -// let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); - -// let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); -// let mut bundle = FluentBundle::new(vec![langid_en]); -// bundle.add_resource(res).unwrap(); - -// let error = crate::validation::Error::Fluent(Message { -// id: "hello-world", -// args: vec![], -// }); - -// assert_eq!(error.try_localize(&bundle), Ok("Hello, world!".to_string())); -// } - -// #[test] -// fn try_localize_with_args() { -// let ftl_string = "intro = Welcome, { $name }.".to_string(); -// let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); - -// let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); -// let mut bundle = FluentBundle::new(vec![langid_en]); -// bundle.add_resource(res).unwrap(); - -// let error = crate::validation::Error::Fluent(Message { -// id: "intro", -// args: vec![("name", FluentValue::from("John"))], -// }); - -// assert_eq!( -// error.try_localize(&bundle), -// Ok("Welcome, \u{2068}John\u{2069}.".to_string()) -// ); -// } - -// #[test] -// fn try_localize_from_validation_error() { -// let ftl_string = "intro = Welcome, { $name }.".to_string(); -// let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); - -// let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); -// let mut bundle = FluentBundle::new(vec![langid_en]); -// bundle.add_resource(res).unwrap(); - -// let error = crate::validation::Error::Maximum( -// Format::Fluent(Message { -// id: "intro", -// args: vec![("name", FluentValue::from("John"))], -// }) -// .into_message(crate::MaximumError { -// maximum: Number::I32(10), -// }), -// ); - -// assert_eq!( -// error.try_localize(&bundle), -// Ok("Welcome, \u{2068}John\u{2069}.".to_string()) -// ); -// } -// } +use fluent_0::{FluentBundle, FluentResource}; + +use crate::validation::error::{ + ArrayErrors, DefaultFormat, Errors, ItemErrorsMap, ObjectErrors, PropertyErrorsMap, VecErrors, +}; + +use super::{LocalizedError, TryLocalize}; + +pub trait Localize { + type Target; + + fn localize(&self, bundle: &FluentBundle) -> Self::Target; +} + +impl Localize for Errors { + type Target = Errors; + + fn localize(&self, bundle: &FluentBundle) -> Self::Target { + match self { + Errors::Array(array) => Errors::Array(array.localize(bundle)), + Errors::Object(object) => Errors::Object(object.localize(bundle)), + Errors::NewType(newtype) => Errors::NewType(newtype.localize(bundle)), + } + } +} + +impl Localize for ArrayErrors { + type Target = ArrayErrors; + + fn localize(&self, bundle: &FluentBundle) -> Self::Target { + ArrayErrors { + errors: self.errors.localize(bundle), + items: self.items.localize(bundle), + } + } +} + +impl Localize for ObjectErrors { + type Target = ObjectErrors; + + fn localize(&self, bundle: &FluentBundle) -> Self::Target { + ObjectErrors { + errors: self.errors.localize(bundle), + properties: self.properties.localize(bundle), + } + } +} + +impl Localize for VecErrors { + type Target = VecErrors; + + fn localize(&self, bundle: &FluentBundle) -> Self::Target { + self.iter().map(|error| error.localize(bundle)).collect() + } +} + +impl Localize for ItemErrorsMap { + type Target = ItemErrorsMap; + + fn localize(&self, bundle: &FluentBundle) -> Self::Target { + self.iter() + .map(|(index, error)| (*index, error.localize(bundle))) + .collect() + } +} + +impl Localize for PropertyErrorsMap { + type Target = PropertyErrorsMap; + + fn localize(&self, bundle: &FluentBundle) -> Self::Target { + self.iter() + .map(|(property, error)| (property.to_string(), error.localize(bundle))) + .collect() + } +} + +impl Localize for crate::validation::Error { + type Target = LocalizedError; + + fn localize(&self, bundle: &FluentBundle) -> Self::Target { + match self { + Self::Minimum(message) => message.localize(bundle), + Self::Maximum(message) => message.localize(bundle), + Self::ExclusiveMinimum(message) => message.localize(bundle), + Self::ExclusiveMaximum(message) => message.localize(bundle), + Self::MultipleOf(message) => message.localize(bundle), + Self::MinLength(message) => message.localize(bundle), + Self::MaxLength(message) => message.localize(bundle), + Self::Pattern(message) => message.localize(bundle), + Self::MinItems(message) => message.localize(bundle), + Self::MaxItems(message) => message.localize(bundle), + Self::UniqueItems(message) => message.localize(bundle), + Self::MinProperties(message) => message.localize(bundle), + Self::MaxProperties(message) => message.localize(bundle), + Self::Enumerate(message) => message.localize(bundle), + Self::Custom(message) => LocalizedError::String(message.to_string()), + Self::Items(message) => LocalizedError::Items(message.localize(bundle)), + Self::Properties(message) => LocalizedError::Properties(message.localize(bundle)), + Self::Fluent(message) => message.localize(bundle).unwrap_or_else(|| { + LocalizedError::String(format!("Fluent id not found: \"{}\"", message.id)) + }), + } + } +} + +impl Localize for crate::validation::error::Message +where + E: DefaultFormat, +{ + type Target = LocalizedError; + + fn localize(&self, bundle: &FluentBundle) -> Self::Target { + self.try_localize(bundle) + .unwrap_or_else(|_| LocalizedError::String(self.default_format())) + } +} + +impl Localize for crate::features::fluent::Message { + type Target = Option; + + fn localize(&self, bundle: &FluentBundle) -> Self::Target { + self.try_localize(bundle) + .unwrap_or_else(|e: Vec| { + Some(LocalizedError::String(format!("FluentErrors: {:?}", e))) + }) + } +} + +#[cfg(test)] +mod test { + use crate::fluent::Message; + + use super::*; + use fluent_0::{bundle::FluentBundle, FluentResource, FluentValue}; + use serde_json::json; + use unic_langid::LanguageIdentifier; + + #[test] + fn localize_without_args() -> crate::tests::Result<()> { + let ftl_string = "hello-world = Hello, world!".to_string(); + let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); + + let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); + let mut bundle = FluentBundle::new(vec![langid_en]); + bundle.add_resource(res).unwrap(); + + let error = crate::validation::Error::Fluent(Message { + id: "hello-world", + args: vec![], + }); + + assert_eq!( + serde_json::to_value(error.localize(&bundle))?, + json!("Hello, world!") + ); + + Ok(()) + } + + #[test] + fn localize_fluetn_id_not_found() -> crate::tests::Result<()> { + let ftl_string = "hello-world = Hello, world!".to_string(); + let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); + + let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); + let mut bundle = FluentBundle::new(vec![langid_en]); + bundle.add_resource(res).unwrap(); + + let error = crate::validation::Error::Fluent(Message { + id: "hello", + args: vec![], + }); + + assert_eq!( + serde_json::to_value(error.localize(&bundle))?, + json!("Fluent id not found: \"hello\"") + ); + + Ok(()) + } + + #[test] + fn try_localize_with_args() -> crate::tests::Result<()> { + let ftl_string = "intro = Welcome, { $name }.".to_string(); + let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); + + let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); + let mut bundle = FluentBundle::new(vec![langid_en]); + bundle.add_resource(res).unwrap(); + + let error = crate::validation::Error::Fluent(Message { + id: "intro", + args: vec![("name", FluentValue::from("John"))], + }); + + assert_eq!( + serde_json::to_value(error.localize(&bundle))?, + json!("Welcome, \u{2068}John\u{2069}.") + ); + + Ok(()) + } + + #[test] + fn try_localize_from_validation_error() -> crate::tests::Result<()> { + let ftl_string = "intro = Welcome, { $name }.".to_string(); + let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); + + let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); + let mut bundle = FluentBundle::new(vec![langid_en]); + bundle.add_resource(res).unwrap(); + + let error = crate::validation::Error::Maximum( + crate::validation::error::Format::Fluent(Message { + id: "intro", + args: vec![("name", FluentValue::from("John"))], + }) + .into_message(crate::MaximumError { + maximum: serde_valid_literal::Number::I32(10), + }), + ); + + assert_eq!( + serde_json::to_value(error.localize(&bundle))?, + json!("Welcome, \u{2068}John\u{2069}.") + ); + + Ok(()) + } +} diff --git a/serde_valid/src/features/fluent/try_localize.rs b/serde_valid/src/features/fluent/try_localize.rs new file mode 100644 index 0000000..0e4a125 --- /dev/null +++ b/serde_valid/src/features/fluent/try_localize.rs @@ -0,0 +1,299 @@ +use fluent_0::{FluentArgs, FluentBundle, FluentError, FluentResource}; + +use crate::validation::error::{ + ArrayErrors, DefaultFormat, Errors, ItemErrorsMap, ObjectErrors, PropertyErrorsMap, VecErrors, +}; + +use super::LocalizedError; + +pub trait TryLocalize { + type Target; + + fn try_localize( + &self, + bundle: &FluentBundle, + ) -> Result>; +} + +impl TryLocalize for Errors { + type Target = Errors; + + fn try_localize( + &self, + bundle: &FluentBundle, + ) -> Result> { + match self { + Errors::Array(array) => Ok(Errors::Array(array.try_localize(bundle)?)), + Errors::Object(object) => Ok(Errors::Object(object.try_localize(bundle)?)), + Errors::NewType(newtype) => Ok(Errors::NewType(newtype.try_localize(bundle)?)), + } + } +} + +impl TryLocalize for ArrayErrors { + type Target = ArrayErrors; + + fn try_localize( + &self, + bundle: &FluentBundle, + ) -> Result> { + match ( + self.errors.try_localize(bundle), + self.items.try_localize(bundle), + ) { + (Ok(errors), Ok(items)) => Ok(ArrayErrors { errors, items }), + (Err(errors), Ok(_)) => Err(errors)?, + (Ok(_), Err(items)) => Err(items)?, + (Err(errors), Err(items)) => Err(errors.into_iter().chain(items).collect()), + } + } +} + +impl TryLocalize for ObjectErrors { + type Target = ObjectErrors; + + fn try_localize( + &self, + bundle: &FluentBundle, + ) -> Result> { + match ( + self.errors.try_localize(bundle), + self.properties.try_localize(bundle), + ) { + (Ok(errors), Ok(properties)) => Ok(ObjectErrors { errors, properties }), + (Err(errors), Ok(_)) => Err(errors)?, + (Ok(_), Err(properties)) => Err(properties)?, + (Err(errors), Err(properties)) => Err(errors.into_iter().chain(properties).collect()), + } + } +} + +impl TryLocalize for VecErrors { + type Target = VecErrors; + + fn try_localize( + &self, + bundle: &FluentBundle, + ) -> Result> { + self.iter() + .map(|error| error.try_localize(bundle)) + .collect() + } +} + +impl TryLocalize for ItemErrorsMap { + type Target = ItemErrorsMap; + + fn try_localize( + &self, + bundle: &FluentBundle, + ) -> Result> { + let mut errors = vec![]; + let target = self + .iter() + .filter_map(|(index, error)| { + error + .try_localize(bundle) + .map(|error| Some((*index, error))) + .unwrap_or_else(|err| { + errors.extend(err); + None + }) + }) + .collect::(); + + if errors.is_empty() { + Ok(target) + } else { + Err(errors) + } + } +} + +impl TryLocalize for PropertyErrorsMap { + type Target = PropertyErrorsMap; + + fn try_localize( + &self, + bundle: &FluentBundle, + ) -> Result> { + let mut errors = vec![]; + let target = self + .iter() + .filter_map(|(properties, error)| { + error + .try_localize(bundle) + .map(|error| Some((properties.clone(), error))) + .unwrap_or_else(|err| { + errors.extend(err); + None + }) + }) + .collect::(); + + if errors.is_empty() { + Ok(target) + } else { + Err(errors) + } + } +} + +impl TryLocalize for crate::validation::Error { + type Target = LocalizedError; + + fn try_localize( + &self, + bundle: &FluentBundle, + ) -> Result> { + match self { + Self::Minimum(message) => message.try_localize(bundle), + Self::Maximum(message) => message.try_localize(bundle), + Self::ExclusiveMinimum(message) => message.try_localize(bundle), + Self::ExclusiveMaximum(message) => message.try_localize(bundle), + Self::MultipleOf(message) => message.try_localize(bundle), + Self::MinLength(message) => message.try_localize(bundle), + Self::MaxLength(message) => message.try_localize(bundle), + Self::Pattern(message) => message.try_localize(bundle), + Self::MinItems(message) => message.try_localize(bundle), + Self::MaxItems(message) => message.try_localize(bundle), + Self::UniqueItems(message) => message.try_localize(bundle), + Self::MinProperties(message) => message.try_localize(bundle), + Self::MaxProperties(message) => message.try_localize(bundle), + Self::Enumerate(message) => message.try_localize(bundle), + Self::Custom(message) => Ok(LocalizedError::String(message.to_string())), + Self::Items(message) => Ok(LocalizedError::Items(message.try_localize(bundle)?)), + Self::Properties(message) => { + Ok(LocalizedError::Properties(message.try_localize(bundle)?)) + } + Self::Fluent(message) => Ok(message + .try_localize(bundle)? + .unwrap_or_else(|| LocalizedError::String(message.id.to_string()))), + } + } +} + +impl TryLocalize for crate::validation::error::Message +where + E: DefaultFormat, +{ + type Target = LocalizedError; + + fn try_localize( + &self, + bundle: &FluentBundle, + ) -> Result> { + if let Some(message) = self.fluent_message() { + if let Some(localized) = message.try_localize(bundle)? { + return Ok(localized); + } + } + Ok(LocalizedError::String(self.default_format())) + } +} + +impl TryLocalize for crate::features::fluent::Message { + type Target = Option; + + fn try_localize( + &self, + bundle: &FluentBundle, + ) -> Result> { + if let Some(msg) = bundle.get_message(self.id) { + if let Some(pattern) = msg.value() { + let mut errors = vec![]; + let args = FluentArgs::from_iter(self.args.to_owned()); + let value = bundle + .format_pattern(pattern, Some(&args), &mut errors) + .to_string(); + if errors.is_empty() { + return Ok(Some(LocalizedError::String(value))); + } else { + return Err(errors); + } + } + } + Ok(None) + } +} + +#[cfg(test)] +mod test { + use crate::fluent::Message; + + use super::*; + use fluent_0::{bundle::FluentBundle, FluentResource, FluentValue}; + use serde_json::json; + use unic_langid::LanguageIdentifier; + + #[test] + fn try_localize_without_args() -> crate::tests::Result<()> { + let ftl_string = "hello-world = Hello, world!".to_string(); + let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); + + let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); + let mut bundle = FluentBundle::new(vec![langid_en]); + bundle.add_resource(res).unwrap(); + + let error = crate::validation::Error::Fluent(Message { + id: "hello-world", + args: vec![], + }); + + assert_eq!( + serde_json::to_value(error.try_localize(&bundle).expect("localization error."))?, + json!("Hello, world!") + ); + + Ok(()) + } + + #[test] + fn try_localize_with_args() -> crate::tests::Result<()> { + let ftl_string = "intro = Welcome, { $name }.".to_string(); + let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); + + let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); + let mut bundle = FluentBundle::new(vec![langid_en]); + bundle.add_resource(res).unwrap(); + + let error = crate::validation::Error::Fluent(Message { + id: "intro", + args: vec![("name", FluentValue::from("John"))], + }); + + assert_eq!( + serde_json::to_value(error.try_localize(&bundle).expect("localization error."))?, + json!("Welcome, \u{2068}John\u{2069}.") + ); + + Ok(()) + } + + #[test] + fn try_localize_from_validation_error() -> crate::tests::Result<()> { + let ftl_string = "intro = Welcome, { $name }.".to_string(); + let res = FluentResource::try_new(ftl_string).expect("Failed to parse an FTL string."); + + let langid_en: LanguageIdentifier = "en-US".parse().expect("Parsing failed"); + let mut bundle = FluentBundle::new(vec![langid_en]); + bundle.add_resource(res).unwrap(); + + let error = crate::validation::Error::Maximum( + crate::validation::error::Format::Fluent(Message { + id: "intro", + args: vec![("name", FluentValue::from("John"))], + }) + .into_message(crate::MaximumError { + maximum: serde_valid_literal::Number::I32(10), + }), + ); + + assert_eq!( + serde_json::to_value(error.try_localize(&bundle).expect("localization error."))?, + json!("Welcome, \u{2068}John\u{2069}.") + ); + + Ok(()) + } +} diff --git a/serde_valid/src/lib.rs b/serde_valid/src/lib.rs index d21fb91..4a6b7de 100644 --- a/serde_valid/src/lib.rs +++ b/serde_valid/src/lib.rs @@ -701,3 +701,8 @@ pub mod helpers { f(data) } } + +#[cfg(test)] +pub mod tests { + pub type Result = std::result::Result>; +} diff --git a/serde_valid/src/validation/error/message.rs b/serde_valid/src/validation/error/message.rs index 0a12154..30bfe84 100644 --- a/serde_valid/src/validation/error/message.rs +++ b/serde_valid/src/validation/error/message.rs @@ -20,17 +20,26 @@ impl Message { } } -impl std::fmt::Display for Message +impl DefaultFormat for Message where E: DefaultFormat, { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.format { - Format::Default => write!(f, "{}", self.error.default_format()), - Format::Message(ref message) => write!(f, "{message}"), - Format::MessageFn(ref format_fn) => write!(f, "{}", { format_fn }(&self.error)), + fn default_format(&self) -> String { + match &self.format { + Format::Default => self.error.default_format(), + Format::Message(ref message) => message.to_string(), + Format::MessageFn(ref format_fn) => format_fn(&self.error), #[cfg(feature = "fluent")] - Format::Fluent(_) => write!(f, "{}", self.error.default_format()), + Format::Fluent(message) => format!("{message}"), } } } + +impl std::fmt::Display for Message +where + E: DefaultFormat, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.default_format()) + } +} From 5d00f1fa9605808db6d9221c01f0e242ffa1788e Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Sat, 13 Jan 2024 12:15:34 +0900 Subject: [PATCH 23/25] fix: valname. --- serde_valid/src/error.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/serde_valid/src/error.rs b/serde_valid/src/error.rs index 5849283..b857bf6 100644 --- a/serde_valid/src/error.rs +++ b/serde_valid/src/error.rs @@ -52,7 +52,7 @@ where macro_rules! struct_error_params { ( #[derive(Debug, Clone)] - #[default_format=$default_format:literal] + #[default_message=$default_message:literal] pub struct $Error:ident { pub $limit:ident: Vec<$type:ty>, } @@ -77,7 +77,7 @@ macro_rules! struct_error_params { #[inline] fn default_format(&self) -> String { format!( - $default_format, + $default_message, self.$limit.iter().map(|v| format!("{}", v)).join(", ") ) } @@ -86,7 +86,7 @@ macro_rules! struct_error_params { ( #[derive(Debug, Clone)] - #[default_format=$default_format:literal] + #[default_message=$default_message:literal] pub struct $Error:ident { pub $limit:ident: $type:ty, } @@ -107,14 +107,14 @@ macro_rules! struct_error_params { impl DefaultFormat for $Error { #[inline] fn default_format(&self) -> String { - format!($default_format, self.$limit) + format!($default_message, self.$limit) } } }; ( #[derive(Debug, Clone)] - #[default_format=$default_format:literal] + #[default_message=$default_message:literal] pub struct $Error:ident; ) => { #[derive(Debug, Clone)] @@ -123,7 +123,7 @@ macro_rules! struct_error_params { impl DefaultFormat for $Error { #[inline] fn default_format(&self) -> String { - format!($default_format) + format!($default_message) } } }; @@ -132,7 +132,7 @@ macro_rules! struct_error_params { // Number struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The number must be `>= {}`."] + #[default_message = "The number must be `>= {}`."] pub struct MinimumError { pub minimum: Number, } @@ -140,7 +140,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The number must be `<= {}`."] + #[default_message = "The number must be `<= {}`."] pub struct MaximumError { pub maximum: Number, } @@ -148,7 +148,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The number must be `> {}`."] + #[default_message = "The number must be `> {}`."] pub struct ExclusiveMinimumError { pub exclusive_minimum: Number, } @@ -156,7 +156,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The number must be `< {}`."] + #[default_message = "The number must be `< {}`."] pub struct ExclusiveMaximumError { pub exclusive_maximum: Number, } @@ -164,7 +164,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The value must be multiple of `{}`."] + #[default_message = "The value must be multiple of `{}`."] pub struct MultipleOfError { pub multiple_of: Number, } @@ -173,7 +173,7 @@ struct_error_params!( // String struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The length of the value must be `>= {}`."] + #[default_message = "The length of the value must be `>= {}`."] pub struct MinLengthError { pub min_length: usize, } @@ -181,7 +181,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The length of the value must be `<= {}`."] + #[default_message = "The length of the value must be `<= {}`."] pub struct MaxLengthError { pub max_length: usize, } @@ -189,7 +189,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The value must match the pattern of \"{0}\"."] + #[default_message = "The value must match the pattern of \"{0}\"."] pub struct PatternError { pub pattern: String, } @@ -198,7 +198,7 @@ struct_error_params!( // Array struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The length of the items must be `<= {}`."] + #[default_message = "The length of the items must be `<= {}`."] pub struct MaxItemsError { pub max_items: usize, } @@ -206,7 +206,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The length of the items must be `>= {}`."] + #[default_message = "The length of the items must be `>= {}`."] pub struct MinItemsError { pub min_items: usize, } @@ -214,14 +214,14 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The items must be unique."] + #[default_message = "The items must be unique."] pub struct UniqueItemsError; ); // Object struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The size of the properties must be `<= {}`."] + #[default_message = "The size of the properties must be `<= {}`."] pub struct MaxPropertiesError { pub max_properties: usize, } @@ -229,7 +229,7 @@ struct_error_params!( struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The size of the properties must be `>= {}`."] + #[default_message = "The size of the properties must be `>= {}`."] pub struct MinPropertiesError { pub min_properties: usize, } @@ -238,7 +238,7 @@ struct_error_params!( // Generic struct_error_params!( #[derive(Debug, Clone)] - #[default_format = "The value must be in [{:}]."] + #[default_message = "The value must be in [{:}]."] pub struct EnumerateError { pub enumerate: Vec, } From 0115d63685e84e2816688ddd9f1bb0f6fb738d71 Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Sat, 13 Jan 2024 12:18:08 +0900 Subject: [PATCH 24/25] rename: trait. --- serde_valid/src/error.rs | 14 +++++++------- serde_valid/src/features/flatten/into_flat.rs | 4 ++-- serde_valid/src/features/fluent/localize.rs | 6 +++--- serde_valid/src/features/fluent/try_localize.rs | 6 +++--- serde_valid/src/validation/error.rs | 2 +- serde_valid/src/validation/error/format.rs | 4 ++-- serde_valid/src/validation/error/message.rs | 14 +++++++------- .../attribute/field_validate/array/length_items.rs | 2 +- .../attribute/field_validate/array/unique_items.rs | 2 +- .../attribute/field_validate/generic/enumerate.rs | 2 +- .../field_validate/numeric/multiple_of.rs | 2 +- .../src/attribute/field_validate/numeric/range.rs | 2 +- .../field_validate/object/size_properties.rs | 2 +- .../src/attribute/field_validate/string/length.rs | 2 +- .../src/attribute/field_validate/string/pattern.rs | 2 +- 15 files changed, 33 insertions(+), 33 deletions(-) diff --git a/serde_valid/src/error.rs b/serde_valid/src/error.rs index b857bf6..be35215 100644 --- a/serde_valid/src/error.rs +++ b/serde_valid/src/error.rs @@ -1,7 +1,7 @@ use itertools::Itertools; use serde_valid_literal::Literal; -use crate::validation::error::DefaultFormat; +use crate::validation::error::FormatDefault; use crate::validation::Number; #[derive(Debug, thiserror::Error)] @@ -73,9 +73,9 @@ macro_rules! struct_error_params { } } - impl DefaultFormat for $Error { + impl FormatDefault for $Error { #[inline] - fn default_format(&self) -> String { + fn format_default(&self) -> String { format!( $default_message, self.$limit.iter().map(|v| format!("{}", v)).join(", ") @@ -104,9 +104,9 @@ macro_rules! struct_error_params { } } - impl DefaultFormat for $Error { + impl FormatDefault for $Error { #[inline] - fn default_format(&self) -> String { + fn format_default(&self) -> String { format!($default_message, self.$limit) } } @@ -120,9 +120,9 @@ macro_rules! struct_error_params { #[derive(Debug, Clone)] pub struct $Error; - impl DefaultFormat for $Error { + impl FormatDefault for $Error { #[inline] - fn default_format(&self) -> String { + fn format_default(&self) -> String { format!($default_message) } } diff --git a/serde_valid/src/features/flatten/into_flat.rs b/serde_valid/src/features/flatten/into_flat.rs index 7194219..3afae21 100644 --- a/serde_valid/src/features/flatten/into_flat.rs +++ b/serde_valid/src/features/flatten/into_flat.rs @@ -1,7 +1,7 @@ use jsonschema::paths::{JSONPointer, PathChunk}; use crate::validation::error::{ - ArrayErrors, DefaultFormat, ItemErrorsMap, Message, ObjectErrors, PropertyErrorsMap, + ArrayErrors, FormatDefault, ItemErrorsMap, Message, ObjectErrors, PropertyErrorsMap, }; use super::{FlatError, FlatErrors}; @@ -109,7 +109,7 @@ where impl IntoFlat for Message where - T: DefaultFormat, + T: FormatDefault, { fn into_flat_at(self, path: &JSONPointer) -> FlatErrors { FlatErrors::new(vec![FlatError::new(path.to_owned(), self.to_string())]) diff --git a/serde_valid/src/features/fluent/localize.rs b/serde_valid/src/features/fluent/localize.rs index 5355f94..5f1ed63 100644 --- a/serde_valid/src/features/fluent/localize.rs +++ b/serde_valid/src/features/fluent/localize.rs @@ -1,7 +1,7 @@ use fluent_0::{FluentBundle, FluentResource}; use crate::validation::error::{ - ArrayErrors, DefaultFormat, Errors, ItemErrorsMap, ObjectErrors, PropertyErrorsMap, VecErrors, + ArrayErrors, Errors, FormatDefault, ItemErrorsMap, ObjectErrors, PropertyErrorsMap, VecErrors, }; use super::{LocalizedError, TryLocalize}; @@ -105,13 +105,13 @@ impl Localize for crate::validation::Error { impl Localize for crate::validation::error::Message where - E: DefaultFormat, + E: FormatDefault, { type Target = LocalizedError; fn localize(&self, bundle: &FluentBundle) -> Self::Target { self.try_localize(bundle) - .unwrap_or_else(|_| LocalizedError::String(self.default_format())) + .unwrap_or_else(|_| LocalizedError::String(self.format_default())) } } diff --git a/serde_valid/src/features/fluent/try_localize.rs b/serde_valid/src/features/fluent/try_localize.rs index 0e4a125..7d7715a 100644 --- a/serde_valid/src/features/fluent/try_localize.rs +++ b/serde_valid/src/features/fluent/try_localize.rs @@ -1,7 +1,7 @@ use fluent_0::{FluentArgs, FluentBundle, FluentError, FluentResource}; use crate::validation::error::{ - ArrayErrors, DefaultFormat, Errors, ItemErrorsMap, ObjectErrors, PropertyErrorsMap, VecErrors, + ArrayErrors, Errors, FormatDefault, ItemErrorsMap, ObjectErrors, PropertyErrorsMap, VecErrors, }; use super::LocalizedError; @@ -175,7 +175,7 @@ impl TryLocalize for crate::validation::Error { impl TryLocalize for crate::validation::error::Message where - E: DefaultFormat, + E: FormatDefault, { type Target = LocalizedError; @@ -188,7 +188,7 @@ where return Ok(localized); } } - Ok(LocalizedError::String(self.default_format())) + Ok(LocalizedError::String(self.format_default())) } } diff --git a/serde_valid/src/validation/error.rs b/serde_valid/src/validation/error.rs index 4a01197..fe6c42c 100644 --- a/serde_valid/src/validation/error.rs +++ b/serde_valid/src/validation/error.rs @@ -12,7 +12,7 @@ pub use crate::error::{ }; pub use array_erros::ArrayErrors; pub use errors::Errors; -pub use format::{DefaultFormat, Format}; +pub use format::{Format, FormatDefault}; use indexmap::IndexMap; pub use into_error::IntoError; pub use message::Message; diff --git a/serde_valid/src/validation/error/format.rs b/serde_valid/src/validation/error/format.rs index 53a8825..06e70d8 100644 --- a/serde_valid/src/validation/error/format.rs +++ b/serde_valid/src/validation/error/format.rs @@ -14,6 +14,6 @@ impl Format { } } -pub trait DefaultFormat { - fn default_format(&self) -> String; +pub trait FormatDefault { + fn format_default(&self) -> String; } diff --git a/serde_valid/src/validation/error/message.rs b/serde_valid/src/validation/error/message.rs index 30bfe84..6df1abf 100644 --- a/serde_valid/src/validation/error/message.rs +++ b/serde_valid/src/validation/error/message.rs @@ -1,4 +1,4 @@ -use super::{DefaultFormat, Format}; +use super::{Format, FormatDefault}; #[derive(Debug, Clone)] pub struct Message { @@ -20,13 +20,13 @@ impl Message { } } -impl DefaultFormat for Message +impl FormatDefault for Message where - E: DefaultFormat, + E: FormatDefault, { - fn default_format(&self) -> String { + fn format_default(&self) -> String { match &self.format { - Format::Default => self.error.default_format(), + Format::Default => self.error.format_default(), Format::Message(ref message) => message.to_string(), Format::MessageFn(ref format_fn) => format_fn(&self.error), #[cfg(feature = "fluent")] @@ -37,9 +37,9 @@ where impl std::fmt::Display for Message where - E: DefaultFormat, + E: FormatDefault, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.default_format()) + write!(f, "{}", self.format_default()) } } diff --git a/serde_valid_derive/src/attribute/field_validate/array/length_items.rs b/serde_valid_derive/src/attribute/field_validate/array/length_items.rs index c4b2030..9d061cf 100644 --- a/serde_valid_derive/src/attribute/field_validate/array/length_items.rs +++ b/serde_valid_derive/src/attribute/field_validate/array/length_items.rs @@ -39,7 +39,7 @@ macro_rules! extract_array_length_validator{ #field_ident, #[<$ErrorType:snake>], ) { - use ::serde_valid::validation::error::DefaultFormat; + use ::serde_valid::validation::error::FormatDefault; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs b/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs index cbb3b5a..c21fe92 100644 --- a/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs +++ b/serde_valid_derive/src/attribute/field_validate/array/unique_items.rs @@ -28,7 +28,7 @@ fn inner_extract_array_unique_items_validator( if let Err(error_params) = ::serde_valid::ValidateUniqueItems::validate_unique_items( #field_ident ) { - use ::serde_valid::validation::error::DefaultFormat; + use ::serde_valid::validation::error::FormatDefault; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs index 14271ce..27ddbc9 100644 --- a/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs +++ b/serde_valid_derive/src/attribute/field_validate/generic/enumerate.rs @@ -34,7 +34,7 @@ fn inner_extract_generic_enumerate_validator( &[#enumerate], ) { use ::serde_valid::validation::IntoError; - use ::serde_valid::validation::error::DefaultFormat; + use ::serde_valid::validation::error::FormatDefault; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs index 3567802..556baf3 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/multiple_of.rs @@ -34,7 +34,7 @@ fn inner_extract_numeric_multiple_of_validator( #multiple_of, ) { use ::serde_valid::validation::IntoError; - use ::serde_valid::validation::error::DefaultFormat; + use ::serde_valid::validation::error::FormatDefault; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs index e7c74a5..8d98268 100644 --- a/serde_valid_derive/src/attribute/field_validate/numeric/range.rs +++ b/serde_valid_derive/src/attribute/field_validate/numeric/range.rs @@ -40,7 +40,7 @@ macro_rules! extract_numeric_range_validator{ #[<$ErrorType:snake>], ) { use ::serde_valid::validation::IntoError; - use ::serde_valid::validation::error::DefaultFormat; + use ::serde_valid::validation::error::FormatDefault; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs index 2fe82e9..d3a2d61 100644 --- a/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs +++ b/serde_valid_derive/src/attribute/field_validate/object/size_properties.rs @@ -40,7 +40,7 @@ macro_rules! extract_object_size_validator { #[<$ErrorType:snake>] ) { use ::serde_valid::validation::IntoError; - use ::serde_valid::validation::error::DefaultFormat; + use ::serde_valid::validation::error::FormatDefault; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/string/length.rs b/serde_valid_derive/src/attribute/field_validate/string/length.rs index e106450..40b3466 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/length.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/length.rs @@ -40,7 +40,7 @@ macro_rules! extract_string_length_validator{ #[<$ErrorType:snake>], ) { use ::serde_valid::validation::IntoError; - use ::serde_valid::validation::error::DefaultFormat; + use ::serde_valid::validation::error::FormatDefault; #errors .entry(#rename) diff --git a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs index 6d9c363..c282f66 100644 --- a/serde_valid_derive/src/attribute/field_validate/string/pattern.rs +++ b/serde_valid_derive/src/attribute/field_validate/string/pattern.rs @@ -40,7 +40,7 @@ fn inner_extract_string_pattern_validator( __pattern, ) { use ::serde_valid::validation::IntoError; - use ::serde_valid::validation::error::DefaultFormat; + use ::serde_valid::validation::error::FormatDefault; #errors .entry(#rename) From 5c6c882854c4452743a5b9b530dce9bc6e725bbc Mon Sep 17 00:00:00 2001 From: yassun7010 Date: Sat, 13 Jan 2024 12:20:37 +0900 Subject: [PATCH 25/25] fix: test code. --- serde_valid/src/features/flatten/into_flat.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/serde_valid/src/features/flatten/into_flat.rs b/serde_valid/src/features/flatten/into_flat.rs index 3afae21..b4ca5ba 100644 --- a/serde_valid/src/features/flatten/into_flat.rs +++ b/serde_valid/src/features/flatten/into_flat.rs @@ -203,29 +203,29 @@ mod tests { FlatErrors::new(vec![ FlatError::new( JSONPointer::default(), - min_items.to_string(), + min_items.format_default(), ), FlatError::new( JSONPointer::from([PathChunk::from(0)].as_ref()), - maximum.to_string(), + maximum.format_default(), ), FlatError::new( JSONPointer::from([PathChunk::from(0), PathChunk::from(2)].as_ref()), - maximum.to_string(), + maximum.format_default(), ), FlatError::new( JSONPointer::from([PathChunk::from(3)].as_ref()), - maximum.to_string(), + maximum.format_default(), ), FlatError::new( JSONPointer::from([PathChunk::from(5)].as_ref()), - maximum.to_string(), + maximum.format_default(), ), FlatError::new( JSONPointer::from( [PathChunk::from(5), PathChunk::from("name".to_owned())].as_ref() ), - maximum.to_string(), + maximum.format_default(), ) ]) );