asia/
asia.rs

1crate::ix!();
2
3//-------------------------------------------------------------
4// AsiaRegion Enum
5//-------------------------------------------------------------
6#[derive(OsmPbfFileDownloader,Debug,PartialOrd,Ord,PartialEq,Eq,Hash,Clone,Copy,StrumDisplay,StrumEnumIter,StrumEnumVariantNames)]
7#[strum(ascii_case_insensitive, serialize_all = "title_case")]
8pub enum AsiaRegion {
9
10    #[geofabrik(asia="afghanistan-latest.osm.pbf")]
11    Afghanistan,
12
13    #[geofabrik(asia="armenia-latest.osm.pbf")]
14    Armenia,
15
16    #[geofabrik(asia="azerbaijan-latest.osm.pbf")]
17    Azerbaijan,
18
19    #[geofabrik(asia="bangladesh-latest.osm.pbf")]
20    Bangladesh,
21
22    #[geofabrik(asia="bhutan-latest.osm.pbf")]
23    Bhutan,
24
25    #[geofabrik(asia="cambodia-latest.osm.pbf")]
26    Cambodia,
27
28    China(ChinaRegion),
29
30    #[geofabrik(asia="east-timor-latest.osm.pbf")]
31    EastTimor,
32
33    #[strum(serialize = "GCC States")]
34    #[geofabrik(asia="gcc-states-latest.osm.pbf")]
35    GccStates, // Bahrain, Kuwait, Oman, Qatar, Saudi Arabia, UAE combined
36
37    India(IndiaRegion),
38
39    Indonesia(IndonesiaRegion),
40
41    #[geofabrik(asia="iran-latest.osm.pbf")]
42    Iran,
43
44    #[geofabrik(asia="iraq-latest.osm.pbf")]
45    Iraq,
46
47    #[strum(serialize = "Israel and Palestine")]
48    #[geofabrik(asia="israel-and-palestine-latest.osm.pbf")]
49    IsraelAndPalestine,
50
51    Japan(JapanRegion),
52
53    #[geofabrik(asia="jordan-latest.osm.pbf")]
54    Jordan,
55
56    #[geofabrik(asia="kazakhstan-latest.osm.pbf")]
57    Kazakhstan,
58
59    #[geofabrik(asia="kyrgyzstan-latest.osm.pbf")]
60    Kyrgyzstan,
61
62    #[geofabrik(asia="laos-latest.osm.pbf")]
63    Laos,
64
65    #[geofabrik(asia="lebanon-latest.osm.pbf")]
66    Lebanon,
67
68    #[strum(serialize = "Malaysia, Singapore, and Brunei")]
69    #[geofabrik(asia="malaysia-singapore-brunei-latest.osm.pbf")]
70    MalaysiaSingaporeBrunei, // Malaysia, Singapore, Brunei combined
71
72    #[geofabrik(asia="maldives-latest.osm.pbf")]
73    Maldives,
74
75    #[geofabrik(asia="mongolia-latest.osm.pbf")]
76    Mongolia,
77
78    #[geofabrik(asia="myanmar-latest.osm.pbf")]
79    Myanmar,
80
81    #[geofabrik(asia="nepal-latest.osm.pbf")]
82    Nepal,
83
84    #[geofabrik(asia="north-korea-latest.osm.pbf")]
85    NorthKorea,
86
87    #[geofabrik(asia="pakistan-latest.osm.pbf")]
88    Pakistan,
89
90    #[geofabrik(asia="philippines-latest.osm.pbf")]
91    Philippines,
92
93    RussianFederation(RussianFederationRegion),
94
95    #[geofabrik(asia="south-korea-latest.osm.pbf")]
96    SouthKorea,
97
98    #[geofabrik(asia="sri-lanka-latest.osm.pbf")]
99    SriLanka,
100
101    #[geofabrik(asia="syria-latest.osm.pbf")]
102    Syria,
103
104    #[geofabrik(asia="taiwan-latest.osm.pbf")]
105    Taiwan,
106
107    #[geofabrik(asia="tajikistan-latest.osm.pbf")]
108    Tajikistan,
109
110    #[geofabrik(asia="thailand-latest.osm.pbf")]
111    Thailand,
112
113    #[geofabrik(asia="turkmenistan-latest.osm.pbf")]
114    Turkmenistan,
115
116    #[geofabrik(asia="uzbekistan-latest.osm.pbf")]
117    Uzbekistan,
118
119    #[geofabrik(asia="vietnam-latest.osm.pbf")]
120    Vietnam,
121
122    #[geofabrik(asia="yemen-latest.osm.pbf")]
123    Yemen,
124}
125
126impl Default for AsiaRegion {
127    fn default() -> Self {
128        // Arbitrarily pick a default: China(Xinjiang)
129        AsiaRegion::China(ChinaRegion::default())
130    }
131}
132
133#[cfg(test)]
134mod test_asia_region {
135    use super::*;
136    use serde_json;
137    use std::convert::TryFrom;
138    use std::str::FromStr;
139
140    #[test]
141    fn test_default() {
142        // Default should be China(Xinjiang)
143        let def = AsiaRegion::default();
144        if let AsiaRegion::China(cr) = def {
145            assert_eq!(cr, ChinaRegion::Xinjiang);
146        } else {
147            panic!("Default AsiaRegion is not China(Xinjiang)!");
148        }
149    }
150
151    #[test]
152    fn test_from_str() {
153        // Check parsing a known non-subdivided variant
154        let parsed = AsiaRegion::from_str("Armenia").expect("Should parse Armenia");
155        assert_eq!(parsed, AsiaRegion::Armenia);
156
157        // Check parsing subdivided: since we only store as maps, we should test via serialization
158        // For direct from_str for AsiaRegion, we rely on strum, which might only parse top-level variants.
159        // Because of the presence of fields, strum might not parse subdivided variants directly from_str.
160        // This is expected. We'll handle subdivided variants through serialization tests.
161    }
162
163    #[test]
164    fn test_abbreviations() {
165        assert_eq!(AsiaRegion::Afghanistan.abbreviation(), "AF");
166        assert_eq!(AsiaRegion::China(ChinaRegion::Beijing).abbreviation(), "CN-BJ");
167        assert_eq!(AsiaRegion::India(IndiaRegion::CentralZone).abbreviation(), "IN-CZ");
168        assert_eq!(AsiaRegion::IsraelAndPalestine.abbreviation(), "IL-PS");
169        assert_eq!(AsiaRegion::MalaysiaSingaporeBrunei.abbreviation(), "MY-SG-BN");
170        assert_eq!(AsiaRegion::RussianFederation(RussianFederationRegion::CentralFederalDistrict).abbreviation(), "RU-CFD");
171    }
172
173    #[test]
174    fn test_europe_region_variants_listed() {
175        // Ensure AsiaRegion variants are accessible:
176        let variants = AsiaRegion::VARIANTS;
177        assert!(variants.contains(&"Armenia"));
178        assert!(variants.contains(&"China"));
179        assert!(variants.contains(&"Japan"));
180    }
181
182    #[test]
183    fn test_asia_region_to_country_success() {
184        assert_eq!(Country::try_from(AsiaRegion::Afghanistan).unwrap(), Country::Afghanistan);
185        assert_eq!(Country::try_from(AsiaRegion::Iran).unwrap(), Country::Iran);
186        assert_eq!(Country::try_from(AsiaRegion::China(ChinaRegion::Hebei)).unwrap(), Country::China);
187        assert_eq!(Country::try_from(AsiaRegion::India(IndiaRegion::SouthernZone)).unwrap(), Country::India);
188        assert_eq!(Country::try_from(AsiaRegion::Indonesia(IndonesiaRegion::Sumatra)).unwrap(), Country::Indonesia);
189        assert_eq!(Country::try_from(AsiaRegion::Japan(JapanRegion::Kanto)).unwrap(), Country::Japan);
190        assert_eq!(Country::try_from(AsiaRegion::RussianFederation(RussianFederationRegion::SiberianFederalDistrict)).unwrap(), Country::Russia);
191        assert_eq!(Country::try_from(AsiaRegion::Nepal).unwrap(), Country::Nepal);
192
193        // Special combined regions:
194        // IsraelAndPalestine -> Israel
195        assert_eq!(Country::try_from(AsiaRegion::IsraelAndPalestine).unwrap(), Country::Israel);
196        // MalaysiaSingaporeBrunei -> Malaysia
197        assert_eq!(Country::try_from(AsiaRegion::MalaysiaSingaporeBrunei).unwrap(), Country::Malaysia);
198    }
199
200    #[test]
201    fn test_asia_region_to_country_errors() {
202        // GCC States is a combined region not directly mapped to a single country
203        match Country::try_from(AsiaRegion::GccStates) {
204            Err( AsiaRegionConversionError::UnsupportedRegion { .. } ) => {}
205            _ => panic!("Expected UnsupportedRegion for GCC States"),
206        }
207    }
208
209    #[test]
210    fn test_country_to_asia_region_success() {
211        // Simple direct mappings
212        assert_eq!(AsiaRegion::try_from(Country::Afghanistan).unwrap(), AsiaRegion::Afghanistan);
213        assert_eq!(AsiaRegion::try_from(Country::Iran).unwrap(), AsiaRegion::Iran);
214        assert_eq!(AsiaRegion::try_from(Country::China).unwrap(), AsiaRegion::China(ChinaRegion::default()));
215        assert_eq!(AsiaRegion::try_from(Country::India).unwrap(), AsiaRegion::India(IndiaRegion::default()));
216        assert_eq!(AsiaRegion::try_from(Country::Indonesia).unwrap(), AsiaRegion::Indonesia(IndonesiaRegion::default()));
217        assert_eq!(AsiaRegion::try_from(Country::Japan).unwrap(), AsiaRegion::Japan(JapanRegion::default()));
218        assert_eq!(AsiaRegion::try_from(Country::Russia).unwrap(), AsiaRegion::RussianFederation(RussianFederationRegion::default()));
219
220        // Special combined regions:
221        // Israel -> IsraelAndPalestine
222        assert_eq!(AsiaRegion::try_from(Country::Israel).unwrap(), AsiaRegion::IsraelAndPalestine);
223        // Malaysia -> MalaysiaSingaporeBrunei
224        assert_eq!(AsiaRegion::try_from(Country::Malaysia).unwrap(), AsiaRegion::MalaysiaSingaporeBrunei);
225    }
226
227    #[test]
228    fn test_country_to_asia_region_errors() {
229        // Test a non-Asian country:
230        match AsiaRegion::try_from(Country::Brazil) {
231            Err(AsiaRegionConversionError::NotAsian { .. }) => {}
232            _ => panic!("Expected NotAsian for Brazil"),
233        }
234
235        match AsiaRegion::try_from(Country::USA) {
236            Err(AsiaRegionConversionError::NotAsian { .. }) => {}
237            _ => panic!("Expected NotAsian for USA"),
238        }
239    }
240
241    #[test]
242    fn test_iso_code_conversions() {
243        let region = AsiaRegion::Japan(JapanRegion::Hokkaido);
244        let alpha2: Iso3166Alpha2 = region.try_into().unwrap();
245        let alpha3: Iso3166Alpha3 = region.try_into().unwrap();
246        let code: CountryCode = region.try_into().unwrap();
247
248        assert_eq!(alpha2, Iso3166Alpha2::JP);
249        assert_eq!(alpha3, Iso3166Alpha3::JPN);
250        match code {
251            CountryCode::Alpha2(a2) => assert_eq!(a2, Iso3166Alpha2::JP),
252            _ => panic!("Expected Alpha2 code"),
253        }
254    }
255
256    #[test]
257    fn test_serialize_deserialize_non_subdivided() {
258        // Test round-trip for a non-subdivided country
259        let region = AsiaRegion::Laos;
260        let serialized = serde_json::to_string(&region).expect("Serialize");
261        let deserialized: AsiaRegion = serde_json::from_str(&serialized).expect("Deserialize");
262        assert_eq!(region, deserialized);
263    }
264
265    #[test]
266    fn test_serialize_deserialize_subdivided() {
267        // Test round-trip for a subdivided country (China)
268        let region = AsiaRegion::China(ChinaRegion::Beijing);
269        let serialized = serde_json::to_string(&region).expect("Serialize");
270        let deserialized: AsiaRegion = serde_json::from_str(&serialized).expect("Deserialize");
271        assert_eq!(region, deserialized);
272
273        // Test round-trip for a subdivided country (Indonesia)
274        let region2 = AsiaRegion::Indonesia(IndonesiaRegion::Sulawesi);
275        let serialized2 = serde_json::to_string(&region2).expect("Serialize");
276        let deserialized2: AsiaRegion = serde_json::from_str(&serialized2).expect("Deserialize");
277        assert_eq!(region2, deserialized2);
278    }
279
280    #[test]
281    fn test_round_trip_country_asia_region() {
282        // Complex region: IsraelAndPalestine -> Israel -> IsraelAndPalestine
283        let region = AsiaRegion::IsraelAndPalestine;
284        let c: Country = region.try_into().unwrap();
285        assert_eq!(c, Country::Israel);
286        let back: AsiaRegion = c.try_into().unwrap();
287        assert_eq!(back, AsiaRegion::IsraelAndPalestine);
288
289        // Complex region: MalaysiaSingaporeBrunei -> Malaysia -> MalaysiaSingaporeBrunei
290        let region2 = AsiaRegion::MalaysiaSingaporeBrunei;
291        let c2: Country = region2.try_into().unwrap();
292        assert_eq!(c2, Country::Malaysia);
293        let back2: AsiaRegion = c2.try_into().unwrap();
294        assert_eq!(back2, AsiaRegion::MalaysiaSingaporeBrunei);
295    }
296
297    #[test]
298    fn test_error_conditions_iso_codes() {
299        // Test converting a non-mappable AsiaRegion to Country -> ISO codes:
300        // GCC States
301        match Iso3166Alpha2::try_from(AsiaRegion::GccStates) {
302            Err(AsiaRegionConversionError::UnsupportedRegion { .. }) => {}
303            _ => panic!("Expected error for GCC States -> ISO codes"),
304        }
305    }
306}