Skip to main content

wasm_dbms_api/dbms/validate/
email.rs

1use lazy_regex::{Lazy, Regex, lazy_regex};
2
3use crate::prelude::{Validate, Value};
4
5static EMAIL_REGEX: Lazy<Regex> =
6    lazy_regex!(r"^[A-Za-z0-9]{1}[A-Za-z0-9._%+-]*@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$");
7
8/// A validator for email addresses.
9///
10/// This validator checks if a given text value conforms to a standard email format.
11///
12/// # Examples
13///
14/// ```rust
15/// use wasm_dbms_api::prelude::{EmailValidator, Validate, Value};
16///
17/// let validator = EmailValidator;
18/// let valid_email = Value::Text("christian.visintin@gmail.com".into());
19/// let invalid_email = Value::Text("invalid-email".into());
20///
21/// assert!(validator.validate(&valid_email).is_ok());
22/// assert!(validator.validate(&invalid_email).is_err());
23/// ```
24pub struct EmailValidator;
25
26impl Validate for EmailValidator {
27    fn validate(&self, value: &Value) -> crate::prelude::DbmsResult<()> {
28        let Value::Text(text) = value else {
29            return Err(crate::prelude::DbmsError::Validation(
30                "EmailValidator can only be applied to Text values".to_string(),
31            ));
32        };
33
34        if EMAIL_REGEX.is_match(text.as_str()) {
35            Ok(())
36        } else {
37            Err(crate::prelude::DbmsError::Validation(format!(
38                "Value '{text}' is not a valid email address",
39            )))
40        }
41    }
42}
43
44#[cfg(test)]
45mod tests {
46
47    use super::*;
48
49    #[test]
50    fn test_email_validator() {
51        let validator = EmailValidator;
52        let valid_emails = vec![
53            "christian.visintin1997@yahoo.com",
54            "nome.cognome@gmail.com",
55            "user123@outlook.com",
56            "user.name+tag@gmail.com",
57            "info@azienda.it",
58            "support@sub.domain.com",
59            "hello-world@my-site.org",
60            "a@b.co",
61            "test_email@domain.travel",
62            "user99@domain.co.uk",
63        ];
64        let invalid_emails = vec![
65            "",
66            "plainaddress",
67            "@gmail.com",
68            "user@",
69            "user@gmail",
70            "user@gmail.",
71            "user@.com",
72            "user@@gmail.com",
73            //"user@gmail..com",
74            //"user..name@gmail.com",
75            ".user@gmail.com",
76            //"user.@gmail.com",
77            //"user@-gmail.com",
78            //"user@gmail-.com",
79            "user@111.222.333.444",
80            "user@[127.0.0.1]",
81            "\"user\"@gmail.com",
82            "user name@gmail.com",
83        ];
84
85        for email in valid_emails {
86            let value = Value::Text(email.into());
87            assert!(
88                validator.validate(&value).is_ok(),
89                "Expected '{}' to be valid",
90                email
91            );
92        }
93        for email in invalid_emails {
94            let value = Value::Text(email.into());
95            assert!(
96                validator.validate(&value).is_err(),
97                "Expected '{}' to be invalid",
98                email
99            );
100        }
101    }
102}