this repo has no description
1pub const MAX_EMAIL_LENGTH: usize = 254;
2pub const MAX_LOCAL_PART_LENGTH: usize = 64;
3pub const MAX_DOMAIN_LENGTH: usize = 253;
4pub const MAX_DOMAIN_LABEL_LENGTH: usize = 63;
5const EMAIL_LOCAL_SPECIAL_CHARS: &str = ".!#$%&'*+/=?^_`{|}~-";
6pub fn is_valid_email(email: &str) -> bool {
7 let email = email.trim();
8 if email.is_empty() || email.len() > MAX_EMAIL_LENGTH {
9 return false;
10 }
11 let parts: Vec<&str> = email.rsplitn(2, '@').collect();
12 if parts.len() != 2 {
13 return false;
14 }
15 let domain = parts[0];
16 let local = parts[1];
17 if local.is_empty() || local.len() > MAX_LOCAL_PART_LENGTH {
18 return false;
19 }
20 if local.starts_with('.') || local.ends_with('.') {
21 return false;
22 }
23 if local.contains("..") {
24 return false;
25 }
26 for c in local.chars() {
27 if !c.is_ascii_alphanumeric() && !EMAIL_LOCAL_SPECIAL_CHARS.contains(c) {
28 return false;
29 }
30 }
31 if domain.is_empty() || domain.len() > MAX_DOMAIN_LENGTH {
32 return false;
33 }
34 if !domain.contains('.') {
35 return false;
36 }
37 for label in domain.split('.') {
38 if label.is_empty() || label.len() > MAX_DOMAIN_LABEL_LENGTH {
39 return false;
40 }
41 if label.starts_with('-') || label.ends_with('-') {
42 return false;
43 }
44 for c in label.chars() {
45 if !c.is_ascii_alphanumeric() && c != '-' {
46 return false;
47 }
48 }
49 }
50 true
51}
52#[cfg(test)]
53mod tests {
54 use super::*;
55 #[test]
56 fn test_valid_emails() {
57 assert!(is_valid_email("user@example.com"));
58 assert!(is_valid_email("user.name@example.com"));
59 assert!(is_valid_email("user+tag@example.com"));
60 assert!(is_valid_email("user@sub.example.com"));
61 assert!(is_valid_email("USER@EXAMPLE.COM"));
62 assert!(is_valid_email("user123@example123.com"));
63 assert!(is_valid_email("a@b.co"));
64 }
65 #[test]
66 fn test_invalid_emails() {
67 assert!(!is_valid_email(""));
68 assert!(!is_valid_email("user"));
69 assert!(!is_valid_email("user@"));
70 assert!(!is_valid_email("@example.com"));
71 assert!(!is_valid_email("user@example"));
72 assert!(!is_valid_email("user@@example.com"));
73 assert!(!is_valid_email("user@.example.com"));
74 assert!(!is_valid_email("user@example..com"));
75 assert!(!is_valid_email(".user@example.com"));
76 assert!(!is_valid_email("user.@example.com"));
77 assert!(!is_valid_email("user..name@example.com"));
78 assert!(!is_valid_email("user@-example.com"));
79 assert!(!is_valid_email("user@example-.com"));
80 }
81 #[test]
82 fn test_trimmed_whitespace() {
83 assert!(is_valid_email(" user@example.com "));
84 }
85}