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