ic_dbms_api/validate/
phone.rs1use ic_dbms_api::prelude::Value;
2use lazy_regex::{Lazy, Regex, lazy_regex};
3
4use crate::prelude::Validate;
5
6static PHONE_REGEX: Lazy<Regex> = lazy_regex!(r"^\+?[0-9\s().-]{7,20}$");
7
8pub struct PhoneNumberValidator;
31
32impl Validate for PhoneNumberValidator {
33 fn validate(&self, value: &Value) -> ic_dbms_api::prelude::IcDbmsResult<()> {
34 let Value::Text(text) = value else {
35 return Err(ic_dbms_api::prelude::IcDbmsError::Validation(
36 "PhoneNumberValidator can only be applied to Text values".to_string(),
37 ));
38 };
39
40 if PHONE_REGEX.is_match(text.as_str()) {
41 Ok(())
42 } else {
43 Err(ic_dbms_api::prelude::IcDbmsError::Validation(format!(
44 "Value '{text}' is not a valid phone number",
45 )))
46 }
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn test_phone_number_validator() {
56 let validator = PhoneNumberValidator;
57 let valid_phones = vec![
58 "+1-202-555-0173",
59 "(202) 555-0173",
60 "+44 20 7946 0958",
61 "202.555.0173",
62 "2025550173",
63 "+91 (22) 1234-5678",
64 "+81-3-1234-5678",
65 "123-456-7890",
66 "+49 30 123456",
67 "+33 366 167 7509",
68 "+33 3661677509",
69 ];
70
71 let invalid_phones = vec![
72 "123-ABC-7890",
73 "++1-202-555-0173",
74 "202 555 0173 ext. 5",
76 "phone:2025550173",
77 "202/555/0173",
78 "202_555_0173",
79 "++44 20 7946 0958",
80 ];
81 for phone in valid_phones {
82 let value = Value::Text(phone.into());
83 assert!(
84 validator.validate(&value).is_ok(),
85 "Expected '{}' to be valid",
86 phone
87 );
88 }
89
90 for phone in invalid_phones {
91 let value = Value::Text(phone.into());
92 assert!(
93 validator.validate(&value).is_err(),
94 "Expected '{}' to be invalid",
95 phone
96 );
97 }
98
99 let non_text_value = Value::Int32(1234567890i32.into());
101 assert!(
102 validator.validate(&non_text_value).is_err(),
103 "Expected non-Text value to be invalid"
104 );
105 }
106}