Skip to content

Commit

Permalink
Fix bug with default type + cargo fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
Keats committed Apr 5, 2024
1 parent 1dd03ed commit b158f53
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 48 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ jobs:
run: |
cargo build --no-default-features
cargo test --no-default-features
cargo build ${{ matrix.rust == 'stable' && '--all-features' || '--no-default-features --features card,unic,derive' }}
cargo test ${{ matrix.rust == 'stable' && '--all-features' || '--no-default-features --features card,unic,derive' }}
cargo build --all-features
cargo test --all-features
4 changes: 2 additions & 2 deletions validator/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ pub trait ValidateArgs<'v_a> {
}

impl<'v_a, T, U> ValidateArgs<'v_a> for Option<T>
where
T: ValidateArgs<'v_a, Args=U>,
where
T: ValidateArgs<'v_a, Args = U>,
{
type Args = U;

Expand Down
13 changes: 9 additions & 4 deletions validator/src/validation/contains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ impl ValidateContains for String {
}

impl<T> ValidateContains for Option<T>
where T: ValidateContains {
where
T: ValidateContains,
{
fn validate_contains(&self, needle: &str) -> bool {
if let Some(v) = self {
v.validate_contains(needle)
Expand All @@ -24,15 +26,18 @@ impl<T> ValidateContains for Option<T>
}

impl<T> ValidateContains for &T
where T: ValidateContains {
where
T: ValidateContains,
{
fn validate_contains(&self, needle: &str) -> bool {
T::validate_contains(self, needle)
}
}

impl<'cow, T> ValidateContains for Cow<'cow, T>
where T: ToOwned + ?Sized,
for<'a> &'a T: ValidateContains
where
T: ToOwned + ?Sized,
for<'a> &'a T: ValidateContains,
{
fn validate_contains(&self, needle: &str) -> bool {
self.as_ref().validate_contains(needle)
Expand Down
27 changes: 16 additions & 11 deletions validator/src/validation/email.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,21 @@ use once_cell::sync::Lazy;
use regex::Regex;
use std::borrow::Cow;

use crate::{ValidateIp};
use crate::ValidateIp;

// Regex from the specs
// https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
// It will mark esoteric email addresses like quoted string as invalid
static EMAIL_USER_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+\z").unwrap()
});
static EMAIL_USER_RE: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+\z").unwrap());
static EMAIL_DOMAIN_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(
r"^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$"
).unwrap()
});
// literal form, ipv4 or ipv6 address (SMTP 4.1.3)
static EMAIL_LITERAL_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"\[([a-fA-F0-9:\.]+)\]\z").unwrap()
});
static EMAIL_LITERAL_RE: Lazy<Regex> =
Lazy::new(|| Regex::new(r"\[([a-fA-F0-9:\.]+)\]\z").unwrap());

/// Checks if the domain is a valid domain and if not, check whether it's an IP
#[must_use]
Expand All @@ -43,7 +41,11 @@ fn validate_domain_part(domain_part: &str) -> bool {
/// that are unfamiliar to most users.
pub trait ValidateEmail {
fn validate_email(&self) -> bool {
let val = if let Some(v) = self.as_email_string() { v } else { return true; };
let val = if let Some(v) = self.as_email_string() {
v
} else {
return true;
};

if val.is_empty() || !val.contains('@') {
return false;
Expand Down Expand Up @@ -80,7 +82,9 @@ pub trait ValidateEmail {
}

impl<T> ValidateEmail for &T
where T: ValidateEmail {
where
T: ValidateEmail,
{
fn as_email_string(&self) -> Option<Cow<str>> {
T::as_email_string(self)
}
Expand All @@ -93,8 +97,9 @@ impl ValidateEmail for String {
}

impl<T> ValidateEmail for Option<T>
where
T: ValidateEmail, {
where
T: ValidateEmail,
{
fn as_email_string(&self) -> Option<Cow<str>> {
let Some(u) = self else {
return None;
Expand Down
19 changes: 11 additions & 8 deletions validator/src/validation/length.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{
borrow::Cow,
cell::{Ref, RefMut},
collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque},
rc::Rc,
sync::Arc,
cell::{Ref, RefMut},
};

#[cfg(feature = "indexmap")]
Expand All @@ -15,8 +15,8 @@ use indexmap::{IndexMap, IndexSet};
/// If you apply it on String, don't forget that the length can be different
/// from the number of visual characters for Unicode
pub trait ValidateLength<T>
where
T: PartialEq + PartialOrd,
where
T: PartialEq + PartialOrd,
{
fn validate_length(&self, min: Option<T>, max: Option<T>, equal: Option<T>) -> bool {
if let Some(length) = self.length() {
Expand Down Expand Up @@ -46,7 +46,9 @@ pub trait ValidateLength<T>
macro_rules! validate_type_that_derefs {
($type_:ty) => {
impl<T> ValidateLength<u64> for $type_
where T: ValidateLength<u64> {
where
T: ValidateLength<u64>,
{
fn length(&self) -> Option<u64> {
T::length(self)
}
Expand Down Expand Up @@ -101,17 +103,18 @@ validate_type_with_len!(IndexSet<T>, T);
validate_type_with_len!(IndexMap<K, V>, K, V);

impl<T> ValidateLength<u64> for Cow<'_, T>
where
T: ToOwned + ?Sized,
for<'a> &'a T: ValidateLength<u64>,
where
T: ToOwned + ?Sized,
for<'a> &'a T: ValidateLength<u64>,
{
fn length(&self) -> Option<u64> {
self.as_ref().length()
}
}

impl<T> ValidateLength<u64> for Option<T>
where T: ValidateLength<u64>,
where
T: ValidateLength<u64>,
{
fn length(&self) -> Option<u64> {
let Some(s) = self else {
Expand Down
17 changes: 12 additions & 5 deletions validator/src/validation/regex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ impl AsRegex for Regex {
}

impl<T> AsRegex for &T
where T: AsRegex {
where
T: AsRegex,
{
fn as_regex(&self) -> Cow<Regex> {
T::as_regex(self)
}
Expand Down Expand Up @@ -56,14 +58,18 @@ pub trait ValidateRegex {
}

impl<T> ValidateRegex for &T
where T: ValidateRegex {
where
T: ValidateRegex,
{
fn validate_regex(&self, regex: impl AsRegex) -> bool {
T::validate_regex(self, regex)
}
}

impl<T> ValidateRegex for Option<T>
where T: ValidateRegex {
where
T: ValidateRegex,
{
fn validate_regex(&self, regex: impl AsRegex) -> bool {
if let Some(h) = self {
T::validate_regex(h, regex)
Expand All @@ -74,8 +80,9 @@ impl<T> ValidateRegex for Option<T>
}

impl<'cow, T> ValidateRegex for Cow<'cow, T>
where T: ToOwned + ?Sized,
for<'a> &'a T: ValidateRegex
where
T: ToOwned + ?Sized,
for<'a> &'a T: ValidateRegex,
{
fn validate_regex(&self, regex: impl AsRegex) -> bool {
self.as_ref().validate_regex(regex)
Expand Down
10 changes: 7 additions & 3 deletions validator/src/validation/urls.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::{
borrow::Cow,
cell::{Ref, RefMut},
rc::Rc,
sync::Arc,
cell::{Ref, RefMut},
};
use url::Url;

Expand All @@ -22,7 +22,9 @@ pub trait ValidateUrl {
macro_rules! validate_type_that_derefs {
($type_:ty) => {
impl<T> ValidateUrl for $type_
where T: ValidateUrl {
where
T: ValidateUrl,
{
fn as_url_string(&self) -> Option<Cow<str>> {
T::as_url_string(self)
}
Expand Down Expand Up @@ -52,7 +54,9 @@ validate_type_of_str!(&str);
validate_type_of_str!(String);

impl<T> ValidateUrl for Option<T>
where T: ValidateUrl {
where
T: ValidateUrl,
{
fn as_url_string(&self) -> Option<Cow<str>> {
let Some(u) = self else {
return None;
Expand Down
16 changes: 14 additions & 2 deletions validator_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use darling::util::{Override, WithOriginal};
use darling::FromDeriveInput;
use proc_macro_error::{abort, proc_macro_error};
use quote::{quote, ToTokens};
use syn::{parse_macro_input, DeriveInput, Field, Path, PathArguments};
use syn::{parse_macro_input, DeriveInput, Field, GenericParam, Path, PathArguments};

use tokens::cards::credit_card_tokens;
use tokens::contains::contains_tokens;
Expand Down Expand Up @@ -336,7 +336,19 @@ pub fn derive_validation(input: proc_macro::TokenStream) -> proc_macro::TokenStr

let struct_generics_quote =
validation_data.generics.params.iter().fold(quote!(), |mut q, g| {
q.extend(quote!(#g, ));
if let GenericParam::Type(t) = g {
// Default types are not allowed in trait impl
if t.default.is_some() {
let mut t2 = t.clone();
t2.default = None;
let g2 = GenericParam::Type(t2);
q.extend(quote!(#g2, ));
} else {
q.extend(quote!(#g, ));
}
} else {
q.extend(quote!(#g, ));
}
q
});

Expand Down
8 changes: 2 additions & 6 deletions validator_derive_tests/tests/complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,7 @@ fn is_fine_with_many_valid_validations() {

#[test]
fn test_can_validate_option_fields_with_lifetime() {
static RE2: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^[a-z]{2}$").unwrap()
});
static RE2: Lazy<Regex> = Lazy::new(|| Regex::new(r"^[a-z]{2}$").unwrap());

#[derive(Debug, Validate)]
struct PutStruct<'a> {
Expand Down Expand Up @@ -119,9 +117,7 @@ fn test_can_validate_option_fields_with_lifetime() {

#[test]
fn test_can_validate_option_fields_without_lifetime() {
static RE2: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^[a-z]{2}$").unwrap()
});
static RE2: Lazy<Regex> = Lazy::new(|| Regex::new(r"^[a-z]{2}$").unwrap());

#[derive(Debug, Validate)]
struct PutStruct {
Expand Down
6 changes: 2 additions & 4 deletions validator_derive_tests/tests/regex.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use once_cell::sync::Lazy;
use std::cell::OnceCell;
use std::sync::{Mutex, OnceLock};
use once_cell::sync::Lazy;

use regex::Regex;
use validator::Validate;

static RE2: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^[a-z]{2}$").unwrap()
});
static RE2: Lazy<Regex> = Lazy::new(|| Regex::new(r"^[a-z]{2}$").unwrap());

static REGEX_ONCE_LOCK: OnceLock<Regex> = OnceLock::new();
static REGEX_MUTEX_ONCE_CELL: Mutex<OnceCell<Regex>> = Mutex::new(OnceCell::new());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use validator::Validate;

#[derive(Validate)]
struct Test<T = ()> {
struct DefaultParameters<T = ()> {
a: T,
}

Expand Down

0 comments on commit b158f53

Please sign in to comment.