1use ic_dbms_api::prelude::Value;
2
3use crate::prelude::Validate;
4
5const ISO_3166_COUNTRIES: &[&str] = &[
6 "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ",
7 "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS",
8 "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN",
9 "CO", "CR", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE",
10 "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG",
11 "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN",
12 "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO",
13 "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI",
14 "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML",
15 "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC",
16 "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH",
17 "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA",
18 "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST",
19 "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR",
20 "TT", "TV", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU",
21 "WF", "WS", "YE", "YT", "ZA", "ZM", "ZW",
22];
23
24const ISO_639_1_COUNTRIES: &[&str] = &[
25 "aa", "ab", "ae", "af", "ak", "am", "an", "ar", "as", "av", "ay", "az", "ba", "be", "bg", "bh",
26 "bi", "bm", "bn", "bo", "br", "bs", "ca", "ce", "ch", "co", "cr", "cs", "cu", "cv", "cy", "da",
27 "de", "dv", "dz", "ee", "el", "en", "eo", "es", "et", "eu", "fa", "ff", "fi", "fj", "fo", "fr",
28 "fy", "ga", "gd", "gl", "gn", "gu", "gv", "ha", "he", "hi", "ho", "hr", "ht", "hu", "hy", "hz",
29 "ia", "id", "ie", "ig", "ii", "ik", "io", "is", "it", "iu", "ja", "jv", "ka", "kg", "ki", "kj",
30 "kk", "kl", "km", "kn", "ko", "kr", "ks", "ku", "kv", "kw", "ky", "la", "lb", "lg", "li", "ln",
31 "lo", "lt", "lu", "lv", "mg", "mh", "mi", "mk", "ml", "mn", "mr", "ms", "mt", "my", "na", "nb",
32 "nd", "ne", "ng", "nl", "nn", "no", "nr", "nv", "ny", "oc", "oj", "om", "or", "os", "pa", "pi",
33 "pl", "ps", "pt", "qu", "rm", "rn", "ro", "ru", "rw", "sa", "sc", "sd", "se", "sg", "si", "sk",
34 "sl", "sm", "sn", "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "ta", "te", "tg", "th", "ti",
35 "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw", "ty", "ug", "uk", "ur", "uz", "ve", "vi", "vo",
36 "wa", "wo", "xh", "yi", "yo", "za", "zh", "zu",
37];
38
39pub struct CountryIso3166Validator;
54
55impl Validate for CountryIso3166Validator {
56 fn validate(&self, value: &Value) -> ic_dbms_api::prelude::IcDbmsResult<()> {
57 let Value::Text(text) = value else {
58 return Err(ic_dbms_api::prelude::IcDbmsError::Validation(
59 "Country ISO3166 validator only works on text values".to_string(),
60 ));
61 };
62
63 if !ISO_3166_COUNTRIES.contains(&text.as_str()) {
64 return Err(ic_dbms_api::prelude::IcDbmsError::Validation(format!(
65 "Value '{}' is not a valid ISO3166 country code",
66 text
67 )));
68 }
69
70 Ok(())
71 }
72}
73
74pub struct CountryIso639Validator;
87
88impl Validate for CountryIso639Validator {
89 fn validate(&self, value: &Value) -> ic_dbms_api::prelude::IcDbmsResult<()> {
90 let Value::Text(text) = value else {
91 return Err(ic_dbms_api::prelude::IcDbmsError::Validation(
92 "Country ISO639 validator only works on text values".to_string(),
93 ));
94 };
95
96 if !ISO_639_1_COUNTRIES.contains(&text.as_str()) {
97 return Err(ic_dbms_api::prelude::IcDbmsError::Validation(format!(
98 "Value '{}' is not a valid ISO639 country code",
99 text
100 )));
101 }
102
103 Ok(())
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_country_iso3166_validator() {
113 let validator = CountryIso3166Validator;
114 let valid_country = Value::Text("US".into());
115 let invalid_country = Value::Text("XX".into());
116 let wrong_type = Value::Int32(123i32.into());
117
118 assert!(validator.validate(&valid_country).is_ok());
119 assert!(validator.validate(&invalid_country).is_err());
120 assert!(validator.validate(&wrong_type).is_err());
121 }
122
123 #[test]
124 fn test_country_iso639_validator() {
125 let validator = CountryIso639Validator;
126 let valid_country = Value::Text("en".into());
127 let invalid_country = Value::Text("xx".into());
128 let wrong_type = Value::Int32(123i32.into());
129 assert!(validator.validate(&valid_country).is_ok());
130 assert!(validator.validate(&invalid_country).is_err());
131 assert!(validator.validate(&wrong_type).is_err());
132 }
133}