oxidite_utils/
validation.rs1use regex::Regex;
4
5pub fn is_email(s: &str) -> bool {
7 let re = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap();
8 re.is_match(s)
9}
10
11pub fn is_url(s: &str) -> bool {
13 let re = Regex::new(r"^https?://[a-zA-Z0-9][-a-zA-Z0-9]*(\.[a-zA-Z0-9][-a-zA-Z0-9]*)*(:\d+)?(/.*)?$").unwrap();
14 re.is_match(s)
15}
16
17pub fn is_phone(s: &str) -> bool {
19 let re = Regex::new(r"^\+?[0-9]{10,15}$").unwrap();
20 re.is_match(s.replace(['-', ' ', '(', ')'], "").as_str())
21}
22
23pub fn is_alphanumeric(s: &str) -> bool {
25 !s.is_empty() && s.chars().all(|c| c.is_alphanumeric())
26}
27
28pub fn is_numeric(s: &str) -> bool {
30 !s.is_empty() && s.chars().all(|c| c.is_numeric())
31}
32
33pub fn min_length(s: &str, min: usize) -> bool {
35 s.len() >= min
36}
37
38pub fn max_length(s: &str, max: usize) -> bool {
40 s.len() <= max
41}
42
43pub fn length_between(s: &str, min: usize, max: usize) -> bool {
45 min_length(s, min) && max_length(s, max)
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn test_is_email() {
54 assert!(is_email("test@example.com"));
55 assert!(is_email("user.name+tag@domain.co.uk"));
56 assert!(!is_email("invalid"));
57 assert!(!is_email("@example.com"));
58 }
59
60 #[test]
61 fn test_is_url() {
62 assert!(is_url("https://example.com"));
63 assert!(is_url("http://localhost:3000/path"));
64 assert!(!is_url("not-a-url"));
65 assert!(!is_url("ftp://example.com"));
66 }
67
68 #[test]
69 fn test_is_phone() {
70 assert!(is_phone("+1234567890"));
71 assert!(is_phone("123-456-7890"));
72 assert!(is_phone("(123) 456-7890"));
73 assert!(!is_phone("12345"));
74 }
75
76 #[test]
77 fn test_length_validators() {
78 assert!(min_length("hello", 3));
79 assert!(!min_length("hi", 3));
80 assert!(max_length("hi", 5));
81 assert!(!max_length("hello world", 5));
82 assert!(length_between("hello", 3, 10));
83 }
84}