rustio_admin/admin/
validation.rs1pub fn is_valid_email(s: &str) -> bool {
22 if s.chars().any(char::is_whitespace) {
23 return false;
24 }
25 let mut parts = s.split('@');
26 let (Some(local), Some(domain), None) = (parts.next(), parts.next(), parts.next()) else {
27 return false;
29 };
30 if local.is_empty() || domain.is_empty() {
31 return false;
32 }
33 domain.contains('.') && !domain.starts_with('.') && !domain.ends_with('.')
34}
35
36pub fn is_valid_phone(s: &str) -> bool {
40 if !s
41 .chars()
42 .all(|c| c.is_ascii_digit() || matches!(c, '+' | '-' | '(' | ')' | ' ' | '.'))
43 {
44 return false;
45 }
46 let digits = s.chars().filter(char::is_ascii_digit).count();
47 (7..=15).contains(&digits)
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn email_accepts_typical_addresses() {
56 assert!(is_valid_email("alice@example.com"));
57 assert!(is_valid_email("a.b+tag@sub.example.co.uk"));
58 }
59
60 #[test]
61 fn email_rejects_obvious_typos() {
62 assert!(!is_valid_email("alice"));
63 assert!(!is_valid_email("alice@"));
64 assert!(!is_valid_email("@example.com"));
65 assert!(!is_valid_email("alice@example"));
66 assert!(!is_valid_email("a@b@c.com"));
67 assert!(!is_valid_email("alice @example.com"));
68 assert!(!is_valid_email("alice@.com"));
69 assert!(!is_valid_email("alice@example."));
70 assert!(!is_valid_email(""));
71 }
72
73 #[test]
74 fn phone_accepts_common_shapes() {
75 assert!(is_valid_phone("+1 (555) 123-4567"));
76 assert!(is_valid_phone("0701234567"));
77 assert!(is_valid_phone("555.123.4567"));
78 }
79
80 #[test]
81 fn phone_rejects_letters_and_bad_lengths() {
82 assert!(!is_valid_phone("call me"));
83 assert!(!is_valid_phone("123456")); assert!(!is_valid_phone("1234567890123456")); assert!(!is_valid_phone(""));
86 }
87}