Skip to content

Commit

Permalink
WIP fix option
Browse files Browse the repository at this point in the history
  • Loading branch information
Keats committed Apr 5, 2024
1 parent b158f53 commit 28528cb
Show file tree
Hide file tree
Showing 19 changed files with 235 additions and 89 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## Changelog

## 0.17.1 (unreleased)

- Fix regressions from the derive rewrite


## 0.17.0 (2024/03/04)

- Derive macro has been entirely rewritten
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[workspace]
resolver = "2"
members = ["validator", "validator_derive", "validator_derive_tests"]
members = ["validator", "validator_derive", "validator_derive_tests", "testing-bugs"]
64 changes: 35 additions & 29 deletions validator_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,157 +32,163 @@ impl ToTokens for ValidateField {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let field_name = self.ident.clone().unwrap();
let field_name_str = self.ident.clone().unwrap().to_string();
let (actual_field, wrapper_closure) = self.if_let_option_wrapper(&field_name);

// Length validation
let length = if let Some(length) = self.length.clone() {
length_tokens(length, &field_name, &field_name_str)
wrapper_closure(length_tokens(length, &actual_field, &field_name_str))
} else {
quote!()
};

// Email validation
let email = if let Some(email) = self.email.clone() {
email_tokens(
wrapper_closure(email_tokens(
match email {
Override::Inherit => Email::default(),
Override::Explicit(e) => e,
},
&field_name,
&actual_field,
&field_name_str,
)
))
} else {
quote!()
};

// Credit card validation
let card = if let Some(credit_card) = self.credit_card.clone() {
credit_card_tokens(
wrapper_closure(credit_card_tokens(
match credit_card {
Override::Inherit => Card::default(),
Override::Explicit(c) => c,
},
&field_name,
&actual_field,
&field_name_str,
)
))
} else {
quote!()
};

// Url validation
let url = if let Some(url) = self.url.clone() {
url_tokens(
wrapper_closure(url_tokens(
match url {
Override::Inherit => Url::default(),
Override::Explicit(u) => u,
},
&field_name,
&actual_field,
&field_name_str,
)
))
} else {
quote!()
};

// Ip address validation
let ip = if let Some(ip) = self.ip.clone() {
ip_tokens(
wrapper_closure(ip_tokens(
match ip {
Override::Inherit => Ip::default(),
Override::Explicit(i) => i,
},
&field_name,
&actual_field,
&field_name_str,
)
))
} else {
quote!()
};

// Non control character validation
let ncc = if let Some(ncc) = self.non_control_character.clone() {
non_control_char_tokens(
wrapper_closure(non_control_char_tokens(
match ncc {
Override::Inherit => NonControlCharacter::default(),
Override::Explicit(n) => n,
},
&field_name,
&actual_field,
&field_name_str,
)
))
} else {
quote!()
};

// Range validation
let range = if let Some(range) = self.range.clone() {
range_tokens(range, &field_name, &field_name_str)
wrapper_closure(range_tokens(range, &actual_field, &field_name_str))
} else {
quote!()
};

// Required validation
let required = if let Some(required) = self.required.clone() {
required_tokens(
wrapper_closure(required_tokens(
match required {
Override::Inherit => Required::default(),
Override::Explicit(r) => r,
},
&field_name,
&actual_field,
&field_name_str,
)
))
} else {
quote!()
};

// Required nested validation
let required_nested = if let Some(required_nested) = self.required_nested.clone() {
required_nested_tokens(
wrapper_closure(required_nested_tokens(
match required_nested {
Override::Inherit => Required::default(),
Override::Explicit(r) => r,
},
&field_name,
&actual_field,
&field_name_str,
)
))
} else {
quote!()
};

// Contains validation
let contains = if let Some(contains) = self.contains.clone() {
contains_tokens(contains, &field_name, &field_name_str)
wrapper_closure(contains_tokens(contains, &actual_field, &field_name_str))
} else {
quote!()
};

// Does not contain validation
let does_not_contain = if let Some(does_not_contain) = self.does_not_contain.clone() {
does_not_contain_tokens(does_not_contain, &field_name, &field_name_str)
wrapper_closure(does_not_contain_tokens(
does_not_contain,
&actual_field,
&field_name_str,
))
} else {
quote!()
};

// Must match validation
let must_match = if let Some(must_match) = self.must_match.clone() {
must_match_tokens(must_match, &field_name, &field_name_str)
// TODO: handle option for other
wrapper_closure(must_match_tokens(must_match, &actual_field, &field_name_str))
} else {
quote!()
};

// Regex validation
let regex = if let Some(regex) = self.regex.clone() {
regex_tokens(regex, &field_name, &field_name_str)
wrapper_closure(regex_tokens(regex, &actual_field, &field_name_str))
} else {
quote!()
};

// Custom validation
let custom = if let Some(custom) = self.custom.clone() {
custom_tokens(custom, &field_name, &field_name_str)
wrapper_closure(custom_tokens(custom, &actual_field, &field_name_str))
} else {
quote!()
};

let nested = if let Some(n) = self.nested {
if n {
nested_tokens(&field_name, &field_name_str)
wrapper_closure(nested_tokens(&field_name, &field_name_str))
} else {
quote!()
}
Expand Down
7 changes: 3 additions & 4 deletions validator_derive/src/tokens/cards.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
use quote::quote;
use syn::Ident;

use crate::types::Card;
use crate::utils::{quote_code, quote_message};

pub fn credit_card_tokens(
credit_card: Card,
field_name: &Ident,
field_name: &proc_macro2::TokenStream,
field_name_str: &str,
) -> proc_macro2::TokenStream {
let message = quote_message(credit_card.message);
let code = quote_code(credit_card.code, "credit_card");

quote! {
if !self.#field_name.validate_credit_card() {
if !#field_name.validate_credit_card() {
#code
#message
err.add_param(::std::borrow::Cow::from("value"), &self.#field_name);
err.add_param(::std::borrow::Cow::from("value"), &#field_name);
errors.add(#field_name_str, err);
}
}
Expand Down
7 changes: 3 additions & 4 deletions validator_derive/src/tokens/contains.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use quote::quote;
use syn::Ident;

use crate::types::Contains;
use crate::utils::{quote_code, quote_message};

pub fn contains_tokens(
contains: Contains,
field_name: &Ident,
field_name: &proc_macro2::TokenStream,
field_name_str: &str,
) -> proc_macro2::TokenStream {
let p = contains.pattern;
Expand All @@ -17,11 +16,11 @@ pub fn contains_tokens(
let code = quote_code(contains.code, "contains");

quote! {
if !self.#field_name.validate_contains(#needle) {
if !#field_name.validate_contains(#needle) {
#code
#message
#needle_err
err.add_param(::std::borrow::Cow::from("value"), &self.#field_name);
err.add_param(::std::borrow::Cow::from("value"), &#field_name);
errors.add(#field_name_str, err);
}
}
Expand Down
11 changes: 5 additions & 6 deletions validator_derive/src/tokens/custom.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
use quote::quote;
use syn::Ident;

use crate::types::Custom;
use crate::utils::quote_message;

pub fn custom_tokens(
custom: Custom,
field_name: &Ident,
field_name: &proc_macro2::TokenStream,
field_name_str: &str,
) -> proc_macro2::TokenStream {
let fn_call = custom.function.unwrap();

let args = if let Some(arg) = custom.use_context {
if arg {
quote!(&self.#field_name, args)
quote!(&#field_name, args)
} else {
quote! (&self.#field_name)
quote! (&#field_name)
}
} else {
quote!(&self.#field_name)
quote!(&#field_name)
};

let message = quote_message(custom.message);
Expand All @@ -37,7 +36,7 @@ pub fn custom_tokens(
::std::result::Result::Err(mut err) => {
#code
#message
err.add_param(::std::borrow::Cow::from("value"), &self.#field_name);
err.add_param(::std::borrow::Cow::from("value"), &#field_name);
errors.add(#field_name_str, err);
}
}
Expand Down
7 changes: 3 additions & 4 deletions validator_derive/src/tokens/does_not_contain.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use quote::quote;
use syn::Ident;

use crate::types::DoesNotContain;
use crate::utils::{quote_code, quote_message};

pub fn does_not_contain_tokens(
does_not_contain: DoesNotContain,
field_name: &Ident,
field_name: &proc_macro2::TokenStream,
field_name_str: &str,
) -> proc_macro2::TokenStream {
let p = does_not_contain.pattern;
Expand All @@ -18,11 +17,11 @@ pub fn does_not_contain_tokens(
let code = quote_code(does_not_contain.code, "does_not_contain");

quote! {
if !self.#field_name.validate_does_not_contain(#needle) {
if !#field_name.validate_does_not_contain(#needle) {
#code
#message
#needle_err
err.add_param(::std::borrow::Cow::from("value"), &self.#field_name);
err.add_param(::std::borrow::Cow::from("value"), &#field_name);
errors.add(#field_name_str, err);
}
}
Expand Down
7 changes: 3 additions & 4 deletions validator_derive/src/tokens/email.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
use quote::quote;
use syn::Ident;

use crate::types::Email;
use crate::utils::{quote_code, quote_message};

pub fn email_tokens(
email: Email,
field_name: &Ident,
field_name: &proc_macro2::TokenStream,
field_name_str: &str,
) -> proc_macro2::TokenStream {
let message = quote_message(email.message);
let code = quote_code(email.code, "email");

quote! {
if !self.#field_name.validate_email() {
if !#field_name.validate_email() {
#code
#message
err.add_param(::std::borrow::Cow::from("value"), &self.#field_name);
err.add_param(::std::borrow::Cow::from("value"), &#field_name);
errors.add(#field_name_str, err);
}
}
Expand Down
11 changes: 7 additions & 4 deletions validator_derive/src/tokens/ip.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use quote::quote;
use syn::Ident;

use crate::types::Ip;
use crate::utils::{quote_code, quote_message};

pub fn ip_tokens(ip: Ip, field_name: &Ident, field_name_str: &str) -> proc_macro2::TokenStream {
pub fn ip_tokens(
ip: Ip,
field_name: &proc_macro2::TokenStream,
field_name_str: &str,
) -> proc_macro2::TokenStream {
let message = quote_message(ip.message);
let code = quote_code(ip.code, "ip");

Expand Down Expand Up @@ -32,10 +35,10 @@ pub fn ip_tokens(ip: Ip, field_name: &Ident, field_name_str: &str) -> proc_macro
};

quote! {
if !self.#field_name.#version {
if !#field_name.#version {
#code
#message
err.add_param(::std::borrow::Cow::from("value"), &self.#field_name);
err.add_param(::std::borrow::Cow::from("value"), &#field_name);
errors.add(#field_name_str, err);
}
}
Expand Down
Loading

0 comments on commit 28528cb

Please sign in to comment.