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