-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b8b7889
commit 484bb5a
Showing
8 changed files
with
192 additions
and
197 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
mod custom; | ||
mod enumerate; | ||
mod validate; | ||
|
||
pub use custom::extract_generic_custom_validator; | ||
pub use enumerate::extract_generic_enumerate_validator; | ||
pub use validate::extract_generic_validate_validator; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use crate::field_validate::Validator; | ||
use crate::serde::rename::RenameMap; | ||
use crate::types::Field; | ||
use quote::quote; | ||
|
||
pub fn extract_generic_validate_validator( | ||
field: &impl Field, | ||
rename_map: &RenameMap, | ||
) -> Result<Validator, crate::Errors> { | ||
let field_ident = field.ident(); | ||
let field_name = field.name(); | ||
let field_key = field.key(); | ||
let rename = rename_map.get(field_name).unwrap_or(&field_key); | ||
let errors = field.errors_variable(); | ||
|
||
Ok(quote!( | ||
if let Err(__inner_errors) = #field_ident.validate() { | ||
match __inner_errors { | ||
::serde_valid::validation::Errors::Object(__object_errors) => { | ||
#errors.entry(#rename).or_default().push( | ||
::serde_valid::validation::Error::Properties(__object_errors) | ||
); | ||
} | ||
::serde_valid::validation::Errors::Array(__array_errors) => { | ||
#errors.entry(#rename).or_default().push( | ||
::serde_valid::validation::Error::Items(__array_errors) | ||
); | ||
} | ||
::serde_valid::validation::Errors::NewType(__new_type_errors) => { | ||
#errors.entry(#rename).or_default().extend(__new_type_errors); | ||
} | ||
} | ||
} | ||
)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,150 @@ | ||
mod meta_list; | ||
mod meta_name_value; | ||
mod meta_path; | ||
mod nested_meta_list; | ||
mod nested_meta_name_value; | ||
mod nested_meta_path; | ||
|
||
use crate::field_validate::Validator; | ||
use crate::field_validate::common::{extract_custom_message_tokens, CustomMessageToken}; | ||
use crate::field_validate::{ | ||
MetaListFieldValidation, MetaNameValueFieldValidation, MetaPathFieldValidation, Validator, | ||
}; | ||
use crate::serde::rename::RenameMap; | ||
use crate::types::Field; | ||
use crate::types::SingleIdentPath; | ||
use meta_list::extract_field_validator_from_meta_list; | ||
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 self::meta_list::extract_field_validator_from_meta_list; | ||
use super::generic::extract_generic_validate_validator; | ||
|
||
pub fn extract_field_validator( | ||
field: &impl Field, | ||
attribute: &syn::Attribute, | ||
rename_map: &RenameMap, | ||
) -> Result<Validator, crate::Errors> { | ||
match &attribute.meta { | ||
syn::Meta::List(list) => { | ||
extract_field_validator_from_meta_list(field, attribute, list, rename_map) | ||
} | ||
syn::Meta::Path(_) => extract_field_validator_from_meta_path(field, rename_map), | ||
syn::Meta::List(list) => inner_extract_field_validator(field, attribute, list, rename_map), | ||
syn::Meta::Path(_) => extract_generic_validate_validator(field, rename_map), | ||
syn::Meta::NameValue(name_value) => { | ||
Err(vec![crate::Error::validate_meta_name_value_not_support( | ||
name_value, | ||
)]) | ||
} | ||
} | ||
} | ||
|
||
fn inner_extract_field_validator( | ||
field: &impl Field, | ||
attribute: &syn::Attribute, | ||
meta_list: &syn::MetaList, | ||
rename_map: &RenameMap, | ||
) -> Result<Validator, crate::Errors> { | ||
let mut errors = vec![]; | ||
let nested = meta_list | ||
.parse_args_with(crate::types::CommaSeparatedMetas::parse_terminated) | ||
.map_err(|error| { | ||
vec![crate::Error::validate_attribute_parse_error( | ||
attribute, &error, | ||
)] | ||
})?; | ||
|
||
let custom_message = 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, | ||
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() | ||
} | ||
}; | ||
|
||
let meta = &nested[0]; | ||
|
||
let validation_path = match meta { | ||
syn::Meta::Path(path) => path, | ||
syn::Meta::List(list) => &list.path, | ||
syn::Meta::NameValue(name_value) => &name_value.path, | ||
}; | ||
|
||
let validation_name = SingleIdentPath::new(validation_path).ident().to_string(); | ||
|
||
let validator = match ( | ||
MetaPathFieldValidation::from_str(&validation_name), | ||
MetaListFieldValidation::from_str(&validation_name), | ||
MetaNameValueFieldValidation::from_str(&validation_name), | ||
meta, | ||
) { | ||
(Ok(validation_type), _, _, syn::Meta::Path(validation)) => { | ||
extract_field_validator_from_meta_path( | ||
field, | ||
validation_type, | ||
validation, | ||
custom_message, | ||
rename_map, | ||
) | ||
} | ||
|
||
(_, Ok(validation_type), _, syn::Meta::List(validation)) => { | ||
extract_field_validator_from_meta_list( | ||
field, | ||
validation_type, | ||
validation, | ||
custom_message, | ||
rename_map, | ||
) | ||
} | ||
|
||
(_, _, Ok(validation_type), syn::Meta::NameValue(validation)) => { | ||
extract_field_validator_from_meta_name_value( | ||
field, | ||
validation_type, | ||
validation, | ||
custom_message, | ||
rename_map, | ||
) | ||
} | ||
|
||
(Ok(_), _, _, _) => Err(vec![crate::Error::meta_path_validation_need_value( | ||
validation_path, | ||
&validation_name, | ||
)]), | ||
|
||
(_, Ok(_), _, _) => Err(vec![crate::Error::meta_list_validation_need_value( | ||
validation_path, | ||
&validation_name, | ||
)]), | ||
|
||
(_, _, Ok(_), _) => Err(vec![crate::Error::meta_name_value_validation_need_value( | ||
validation_path, | ||
&validation_name, | ||
)]), | ||
|
||
_ => Err(vec![crate::Error::field_validation_type_unknown( | ||
validation_path, | ||
&validation_name, | ||
)]), | ||
}; | ||
|
||
match validator { | ||
Ok(validator) => { | ||
if errors.is_empty() { | ||
Ok(validator) | ||
} else { | ||
Err(errors) | ||
} | ||
} | ||
Err(validator_errors) => { | ||
errors.extend(validator_errors); | ||
Err(errors) | ||
} | ||
} | ||
} |
129 changes: 13 additions & 116 deletions
129
serde_valid_derive/src/field_validate/meta/meta_list.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,127 +1,24 @@ | ||
use super::nested_meta_list::extract_field_validator_from_nested_meta_list; | ||
use super::nested_meta_name_value::extract_field_validator_from_nested_meta_name_value; | ||
use super::nested_meta_path::extract_field_validator_from_nested_meta_path; | ||
use crate::field_validate::common::{extract_custom_message_tokens, CustomMessageToken}; | ||
use crate::field_validate::{ | ||
MetaListFieldValidation, MetaNameValueFieldValidation, MetaPathFieldValidation, Validator, | ||
use crate::field_validate::common::{CustomMessageToken, MetaListFieldValidation}; | ||
use crate::field_validate::generic::{ | ||
extract_generic_custom_validator, extract_generic_enumerate_validator, | ||
}; | ||
use crate::field_validate::Validator; | ||
use crate::serde::rename::RenameMap; | ||
use crate::types::{Field, SingleIdentPath}; | ||
use std::str::FromStr; | ||
use crate::types::Field; | ||
|
||
pub fn extract_field_validator_from_meta_list( | ||
field: &impl Field, | ||
attribute: &syn::Attribute, | ||
meta_list: &syn::MetaList, | ||
validation_type: MetaListFieldValidation, | ||
validation: &syn::MetaList, | ||
custom_message: CustomMessageToken, | ||
rename_map: &RenameMap, | ||
) -> Result<Validator, crate::Errors> { | ||
let mut errors = vec![]; | ||
let nested = meta_list | ||
.parse_args_with(crate::types::CommaSeparatedMetas::parse_terminated) | ||
.map_err(|error| { | ||
vec![crate::Error::validate_attribute_parse_error( | ||
attribute, &error, | ||
)] | ||
})?; | ||
|
||
let custom_message = 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, | ||
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() | ||
} | ||
}; | ||
|
||
let meta = &nested[0]; | ||
|
||
let validation_path = match meta { | ||
syn::Meta::Path(path) => path, | ||
syn::Meta::List(list) => &list.path, | ||
syn::Meta::NameValue(name_value) => &name_value.path, | ||
}; | ||
|
||
let validation_name = SingleIdentPath::new(validation_path).ident().to_string(); | ||
|
||
let validator = match ( | ||
MetaPathFieldValidation::from_str(&validation_name), | ||
MetaListFieldValidation::from_str(&validation_name), | ||
MetaNameValueFieldValidation::from_str(&validation_name), | ||
meta, | ||
) { | ||
(Ok(validation_type), _, _, syn::Meta::Path(validation)) => { | ||
extract_field_validator_from_nested_meta_path( | ||
field, | ||
validation_type, | ||
validation, | ||
custom_message, | ||
rename_map, | ||
) | ||
} | ||
|
||
(_, Ok(validation_type), _, syn::Meta::List(validation)) => { | ||
extract_field_validator_from_nested_meta_list( | ||
field, | ||
validation_type, | ||
validation, | ||
custom_message, | ||
rename_map, | ||
) | ||
} | ||
|
||
(_, _, Ok(validation_type), syn::Meta::NameValue(validation)) => { | ||
extract_field_validator_from_nested_meta_name_value( | ||
field, | ||
validation_type, | ||
validation, | ||
custom_message, | ||
rename_map, | ||
) | ||
} | ||
|
||
(Ok(_), _, _, _) => Err(vec![crate::Error::meta_path_validation_need_value( | ||
validation_path, | ||
&validation_name, | ||
)]), | ||
|
||
(_, Ok(_), _, _) => Err(vec![crate::Error::meta_list_validation_need_value( | ||
validation_path, | ||
&validation_name, | ||
)]), | ||
|
||
(_, _, Ok(_), _) => Err(vec![crate::Error::meta_name_value_validation_need_value( | ||
validation_path, | ||
&validation_name, | ||
)]), | ||
|
||
_ => Err(vec![crate::Error::field_validation_type_unknown( | ||
validation_path, | ||
&validation_name, | ||
)]), | ||
}; | ||
|
||
match validator { | ||
Ok(validator) => { | ||
if errors.is_empty() { | ||
Ok(validator) | ||
} else { | ||
Err(errors) | ||
} | ||
match validation_type { | ||
MetaListFieldValidation::Enumerate => { | ||
extract_generic_enumerate_validator(field, validation, custom_message, rename_map) | ||
} | ||
Err(validator_errors) => { | ||
errors.extend(validator_errors); | ||
Err(errors) | ||
MetaListFieldValidation::Custom => { | ||
extract_generic_custom_validator(field, validation, rename_map) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.