Skip to content

Commit

Permalink
refactor: validation error handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
yassun7010 committed Jan 6, 2024
1 parent 9ef25ea commit 9b13318
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 136 deletions.
3 changes: 1 addition & 2 deletions serde_valid_derive/src/validate/generic/enumerate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use crate::serde::rename::RenameMap;
use crate::types::Field;
use crate::validate::common::CustomMessageToken;
use crate::validate::Validator;
use proc_macro2::TokenStream;
use quote::quote;

type Lits<'a> = syn::punctuated::Punctuated<syn::Lit, syn::token::Comma>;
Expand All @@ -21,7 +20,7 @@ fn inner_extract_generic_enumerate_validator(
item_list: &syn::MetaList,
custom_message: CustomMessageToken,
rename_map: &RenameMap,
) -> Result<TokenStream, crate::Errors> {
) -> Result<Validator, crate::Errors> {
let field_name = field.name();
let field_ident = field.ident();
let field_key = field.key();
Expand Down
76 changes: 63 additions & 13 deletions serde_valid_derive/src/validate/meta/meta_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use super::nested_meta_list::extract_validator_from_nested_meta_list;
use super::nested_meta_name_value::extract_validator_from_nested_meta_name_value;
use super::nested_meta_path::extract_validator_from_nested_meta_path;
use crate::serde::rename::RenameMap;
use crate::types::Field;
use crate::types::{Field, SingleIdentPath};
use crate::validate::common::{extract_custom_message_tokens, CustomMessageToken};
use crate::validate::Validator;
use crate::validate::{MetaListValidation, MetaNameValueValidation, MetaPathValidation, Validator};
use std::str::FromStr;

pub fn extract_validator_from_meta_list(
field: &impl Field,
Expand Down Expand Up @@ -41,20 +42,69 @@ pub fn extract_validator_from_meta_list(
if !nested.is_empty() {
let meta = &nested[0];

let validator = match meta {
syn::Meta::Path(path) => {
extract_validator_from_nested_meta_path(field, path, custom_message, rename_map)
let validation_path = match meta {
syn::Meta::Path(path) => path,
syn::Meta::List(list) => &list.path,
syn::Meta::NameValue(name_value) => &name_value.path,
};

let validation_name = SingleIdentPath::new(validation_path).ident().to_string();

let validator = match (
MetaPathValidation::from_str(&validation_name),
MetaListValidation::from_str(&validation_name),
MetaNameValueValidation::from_str(&validation_name),
meta,
) {
(Ok(validation_type), _, _, syn::Meta::Path(path)) => {
extract_validator_from_nested_meta_path(
field,
validation_type,
path,
custom_message,
rename_map,
)
}
syn::Meta::List(list) => {
extract_validator_from_nested_meta_list(field, list, custom_message, rename_map)
(_, Ok(validation_type), _, syn::Meta::List(list)) => {
extract_validator_from_nested_meta_list(
field,
validation_type,
list,
custom_message,
rename_map,
)
}
syn::Meta::NameValue(name_value) => extract_validator_from_nested_meta_name_value(
field,
name_value,
custom_message,
rename_map,
),
(_, _, Ok(validation_type), syn::Meta::NameValue(name_value)) => {
extract_validator_from_nested_meta_name_value(
field,
validation_type,
name_value,
custom_message,
rename_map,
)
}
(Ok(_), _, _, _) => Err(vec![crate::Error::validate_meta_path_need_value(
validation_path,
&validation_name,
)]),
(_, Ok(_), _, _) => Err(vec![crate::Error::validate_meta_list_need_value(
validation_path,
&validation_name,
)]),
(_, _, Ok(_), _) => Err(vec![crate::Error::validate_meta_name_value_need_value(
validation_path,
&validation_name,
)]),
_ => Err(vec![crate::Error::validate_unknown_type(
validation_path,
&validation_name,
&(MetaPathValidation::iter().map(|x| x.name()))
.chain(MetaListValidation::iter().map(|x| x.name()))
.chain(MetaNameValueValidation::iter().map(|x| x.name()))
.collect::<Vec<_>>(),
)]),
};

match validator {
Ok(validator) => {
if errors.is_empty() {
Expand Down
39 changes: 6 additions & 33 deletions serde_valid_derive/src/validate/meta/nested_meta_list.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,24 @@
use crate::serde::rename::RenameMap;
use crate::types::{Field, SingleIdentPath};
use crate::types::Field;
use crate::validate::common::{CustomMessageToken, MetaListValidation};
use crate::validate::generic::{
extract_generic_custom_validator, extract_generic_enumerate_validator,
};
use crate::validate::{MetaNameValueValidation, MetaPathValidation, Validator};
use std::str::FromStr;
use crate::validate::Validator;

pub fn extract_validator_from_nested_meta_list(
field: &impl Field,
validation_type: MetaListValidation,
validation: &syn::MetaList,
custom_message: CustomMessageToken,
rename_map: &RenameMap,
) -> Result<Validator, crate::Errors> {
let mut errors = vec![];

let validation_ident = SingleIdentPath::new(&validation.path).ident();
let validation_name = validation_ident.to_string();

match MetaListValidation::from_str(&validation_name) {
Ok(MetaListValidation::Enumerate) => {
match validation_type {
MetaListValidation::Enumerate => {
extract_generic_enumerate_validator(field, validation, custom_message, rename_map)
}
Ok(MetaListValidation::Custom) => {
MetaListValidation::Custom => {
extract_generic_custom_validator(field, validation, rename_map)
}
Err(unknown) => {
let error = if MetaNameValueValidation::from_str(&validation_name).is_ok() {
crate::Error::validate_meta_name_value_need_value(
&validation.path,
&validation_name,
)
} else if MetaPathValidation::from_str(&validation_name).is_ok() {
crate::Error::validate_meta_path_need_value(&validation.path, &validation_name)
} else {
crate::Error::validate_unknown_type(
&validation.path,
&unknown,
&(MetaPathValidation::iter().map(|x| x.name()))
.chain(MetaNameValueValidation::iter().map(|x| x.name()))
.chain(MetaListValidation::iter().map(|x| x.name()))
.collect::<Vec<_>>(),
)
};
errors.push(error);

Err(errors)
}
}
}
82 changes: 26 additions & 56 deletions serde_valid_derive/src/validate/meta/nested_meta_name_value.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::serde::rename::RenameMap;
use crate::types::{Field, SingleIdentPath};
use crate::types::Field;
use crate::validate::array::{
extract_array_max_items_validator, extract_array_min_items_validator,
};
Expand All @@ -16,98 +16,68 @@ use crate::validate::string::{
extract_string_max_length_validator, extract_string_min_length_validator,
extract_string_pattern_validator,
};
use crate::validate::{MetaListValidation, MetaPathValidation, Validator};
use std::str::FromStr;
use crate::validate::Validator;

pub fn extract_validator_from_nested_meta_name_value(
field: &impl Field,
validation_type: MetaNameValueValidation,
validation: &syn::MetaNameValue,
custom_message: CustomMessageToken,
rename_map: &RenameMap,
) -> Result<Validator, crate::Errors> {
let mut errors = vec![];

let validation_ident = SingleIdentPath::new(&validation.path).ident();
let validation_name = validation_ident.to_string();
let validation_value = get_lit(&validation.value)?;

match MetaNameValueValidation::from_str(&validation_name) {
Ok(MetaNameValueValidation::Minimum) => {
match validation_type {
MetaNameValueValidation::Minimum => {
extract_numeric_minimum_validator(field, validation_value, custom_message, rename_map)
}
Ok(MetaNameValueValidation::Maximum) => {
MetaNameValueValidation::Maximum => {
extract_numeric_maximum_validator(field, validation_value, custom_message, rename_map)
}
Ok(MetaNameValueValidation::ExclusiveMinimum) => {
extract_numeric_exclusive_minimum_validator(
field,
validation_value,
custom_message,
rename_map,
)
}
Ok(MetaNameValueValidation::ExclusiveMaximum) => {
extract_numeric_exclusive_maximum_validator(
field,
validation_value,
custom_message,
rename_map,
)
}
Ok(MetaNameValueValidation::MinLength) => {
MetaNameValueValidation::ExclusiveMinimum => extract_numeric_exclusive_minimum_validator(
field,
validation_value,
custom_message,
rename_map,
),
MetaNameValueValidation::ExclusiveMaximum => extract_numeric_exclusive_maximum_validator(
field,
validation_value,
custom_message,
rename_map,
),
MetaNameValueValidation::MinLength => {
extract_string_min_length_validator(field, validation_value, custom_message, rename_map)
}
Ok(MetaNameValueValidation::MaxLength) => {
MetaNameValueValidation::MaxLength => {
extract_string_max_length_validator(field, validation_value, custom_message, rename_map)
}
Ok(MetaNameValueValidation::MinItems) => {
MetaNameValueValidation::MinItems => {
extract_array_min_items_validator(field, validation_value, custom_message, rename_map)
}
Ok(MetaNameValueValidation::MaxItems) => {
MetaNameValueValidation::MaxItems => {
extract_array_max_items_validator(field, validation_value, custom_message, rename_map)
}
Ok(MetaNameValueValidation::MinProperties) => extract_object_min_properties_validator(
MetaNameValueValidation::MinProperties => extract_object_min_properties_validator(
field,
validation_value,
custom_message,
rename_map,
),
Ok(MetaNameValueValidation::MaxProperties) => extract_object_max_properties_validator(
MetaNameValueValidation::MaxProperties => extract_object_max_properties_validator(
field,
validation_value,
custom_message,
rename_map,
),
Ok(MetaNameValueValidation::MultipleOf) => extract_numeric_multiple_of_validator(
MetaNameValueValidation::MultipleOf => extract_numeric_multiple_of_validator(
field,
validation_value,
custom_message,
rename_map,
),
Ok(MetaNameValueValidation::Pattern) => {
MetaNameValueValidation::Pattern => {
extract_string_pattern_validator(field, validation_value, custom_message, rename_map)
}
Err(unknown) => {
let error = if MetaListValidation::from_str(&validation_name).is_ok() {
crate::Error::validate_meta_name_value_need_value(
&validation.path,
&validation_name,
)
} else if MetaPathValidation::from_str(&validation_name).is_ok() {
crate::Error::validate_meta_path_need_value(&validation.path, &validation_name)
} else {
crate::Error::validate_unknown_type(
&validation.path,
&unknown,
&(MetaPathValidation::iter().map(|x| x.name()))
.chain(MetaNameValueValidation::iter().map(|x| x.name()))
.chain(MetaListValidation::iter().map(|x| x.name()))
.collect::<Vec<_>>(),
)
};
errors.push(error);

Err(errors)
}
}
}
38 changes: 6 additions & 32 deletions serde_valid_derive/src/validate/meta/nested_meta_path.rs
Original file line number Diff line number Diff line change
@@ -1,47 +1,21 @@
use crate::serde::rename::RenameMap;
use crate::types::{Field, SingleIdentPath};
use crate::types::Field;
use crate::validate::array::extract_array_unique_items_validator;
use crate::validate::common::{
CustomMessageToken, MetaListValidation, MetaNameValueValidation, MetaPathValidation,
};
use crate::validate::common::{CustomMessageToken, MetaPathValidation};
use crate::validate::Validator;
use std::str::FromStr;

pub fn extract_validator_from_nested_meta_path(
field: &impl Field,
validation: &syn::Path,
validation_type: MetaPathValidation,
_validation: &syn::Path,
custom_message: CustomMessageToken,
rename_map: &RenameMap,
) -> Result<Validator, crate::Errors> {
let mut errors = vec![];

let validation_ident = SingleIdentPath::new(validation).ident();
let validation_name = validation_ident.to_string();

match MetaPathValidation::from_str(&validation_name) {
Ok(MetaPathValidation::UniqueItems) => Ok(extract_array_unique_items_validator(
match validation_type {
MetaPathValidation::UniqueItems => Ok(extract_array_unique_items_validator(
field,
custom_message,
rename_map,
)),
Err(unknown) => {
let error = if MetaNameValueValidation::from_str(&validation_name).is_ok() {
crate::Error::validate_meta_name_value_need_value(validation, &validation_name)
} else if MetaListValidation::from_str(&validation_name).is_ok() {
crate::Error::validate_meta_list_need_value(validation, &validation_name)
} else {
crate::Error::validate_unknown_type(
validation,
&unknown,
&(MetaPathValidation::iter().map(|x| x.name()))
.chain(MetaNameValueValidation::iter().map(|x| x.name()))
.chain(MetaListValidation::iter().map(|x| x.name()))
.collect::<Vec<_>>(),
)
};
errors.push(error);

Err(errors)
}
}
}

0 comments on commit 9b13318

Please sign in to comment.