1#![doc = include_str!("../README.md")]
2
3#[cfg(feature = "serde")]
4mod feature_serde;
5
6#[cfg(feature = "sqlx-postgres")]
7mod feature_sqlx_postgres;
8
9macro_rules! define_country_codes {
10 ($(($code:ident, $name:literal)),* $(,)?) => {
11 #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, PartialOrd, Ord)]
13 pub enum CountryCode {
14 $(
15 #[doc = $name]
16 $code,
17 )*
18 }
19
20 impl CountryCode {
21 pub const ALL: [CountryCode; 250] = [$(CountryCode::$code, )*];
23
24 #[must_use]
26 pub const fn name(&self) -> &'static str {
27 match self {
28 $(
29 CountryCode::$code => $name,
30 )*
31 }
32 }
33 }
34
35 impl std::str::FromStr for CountryCode {
36 type Err = String;
37
38 fn from_str(s: &str) -> Result<Self, Self::Err> {
39 let s = if s.chars().any(|c| c.is_lowercase()) {
40 &s.to_uppercase()
41 } else {
42 s
43 };
44 match s {
45 $(
46 stringify!($code) => Ok(CountryCode::$code),
47 )*
48 _ => Err(format!("Not a country code: {s}")),
49 }
50 }
51 }
52
53 impl From<CountryCode> for &'static str {
54 fn from(value: CountryCode) -> Self {
55 match value {
56 $(
57 CountryCode::$code => stringify!($code),
58 )*
59 }
60 }
61 }
62 };
63}
64
65impl CountryCode {
66 pub fn iter() -> impl Iterator<Item = Self> {
68 Self::ALL.into_iter()
69 }
70}
71
72impl AsRef<str> for CountryCode {
73 fn as_ref(&self) -> &str {
74 <&str>::from(*self)
75 }
76}
77
78impl core::fmt::Display for CountryCode {
79 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
80 core::write!(f, "{}", self.as_ref())
81 }
82}
83
84define_country_codes! {
85 (AD, "Andorra"),
86 (AE, "United Arab Emirates"),
87 (AF, "Afghanistan"),
88 (AG, "Antigua and Barbuda"),
89 (AI, "Anguilla"),
90 (AL, "Albania"),
91 (AM, "Armenia"),
92 (AO, "Angola"),
93 (AQ, "Antarctica"),
94 (AR, "Argentina"),
95 (AS, "American Samoa"),
96 (AT, "Austria"),
97 (AU, "Australia"),
98 (AW, "Aruba"),
99 (AX, "Åland Islands"),
100 (AZ, "Azerbaijan"),
101 (BA, "Bosnia and Herzegovina"),
102 (BB, "Barbados"),
103 (BD, "Bangladesh"),
104 (BE, "Belgium"),
105 (BF, "Burkina Faso"),
106 (BG, "Bulgaria"),
107 (BH, "Bahrain"),
108 (BI, "Burundi"),
109 (BJ, "Benin"),
110 (BL, "Saint Barthélemy"),
111 (BM, "Bermuda"),
112 (BN, "Brunei"),
113 (BO, "Bolivia"),
114 (BQ, "Caribbean Netherlands"),
115 (BR, "Brazil"),
116 (BS, "Bahamas"),
117 (BT, "Bhutan"),
118 (BV, "Bouvet Island"),
119 (BW, "Botswana"),
120 (BY, "Belarus"),
121 (BZ, "Belize"),
122 (CA, "Canada"),
123 (CC, "Cocos (Keeling) Islands"),
124 (CD, "DR Congo"),
125 (CF, "Central African Republic"),
126 (CG, "Congo"),
127 (CH, "Switzerland"),
128 (CI, "Ivory Coast"),
129 (CK, "Cook Islands"),
130 (CL, "Chile"),
131 (CM, "Cameroon"),
132 (CN, "China"),
133 (CO, "Colombia"),
134 (CR, "Costa Rica"),
135 (CU, "Cuba"),
136 (CV, "Cape Verde"),
137 (CW, "Curaçao"),
138 (CX, "Christmas Island"),
139 (CY, "Cyprus"),
140 (CZ, "Czechia"),
141 (DE, "Germany"),
142 (DJ, "Djibouti"),
143 (DK, "Denmark"),
144 (DM, "Dominica"),
145 (DO, "Dominican Republic"),
146 (DZ, "Algeria"),
147 (EC, "Ecuador"),
148 (EE, "Estonia"),
149 (EG, "Egypt"),
150 (EH, "Western Sahara"),
151 (ER, "Eritrea"),
152 (ES, "Spain"),
153 (ET, "Ethiopia"),
154 (FI, "Finland"),
155 (FJ, "Fiji"),
156 (FK, "Falkland Islands"),
157 (FM, "Micronesia"),
158 (FO, "Faroe Islands"),
159 (FR, "France"),
160 (GA, "Gabon"),
161 (GB, "United Kingdom"),
162 (GD, "Grenada"),
163 (GE, "Georgia"),
164 (GF, "French Guiana"),
165 (GG, "Guernsey"),
166 (GH, "Ghana"),
167 (GI, "Gibraltar"),
168 (GL, "Greenland"),
169 (GM, "Gambia"),
170 (GN, "Guinea"),
171 (GP, "Guadeloupe"),
172 (GQ, "Equatorial Guinea"),
173 (GR, "Greece"),
174 (GS, "South Georgia"),
175 (GT, "Guatemala"),
176 (GU, "Guam"),
177 (GW, "Guinea-Bissau"),
178 (GY, "Guyana"),
179 (HK, "Hong Kong"),
180 (HM, "Heard Island and McDonald Islands"),
181 (HN, "Honduras"),
182 (HR, "Croatia"),
183 (HT, "Haiti"),
184 (HU, "Hungary"),
185 (ID, "Indonesia"),
186 (IE, "Ireland"),
187 (IL, "Israel"),
188 (IM, "Isle of Man"),
189 (IN, "India"),
190 (IO, "British Indian Ocean Territory"),
191 (IQ, "Iraq"),
192 (IR, "Iran"),
193 (IS, "Iceland"),
194 (IT, "Italy"),
195 (JE, "Jersey"),
196 (JM, "Jamaica"),
197 (JO, "Jordan"),
198 (JP, "Japan"),
199 (KE, "Kenya"),
200 (KG, "Kyrgyzstan"),
201 (KH, "Cambodia"),
202 (KI, "Kiribati"),
203 (KM, "Comoros"),
204 (KN, "Saint Kitts and Nevis"),
205 (KP, "North Korea"),
206 (KR, "South Korea"),
207 (KW, "Kuwait"),
208 (KY, "Cayman Islands"),
209 (KZ, "Kazakhstan"),
210 (LA, "Laos"),
211 (LB, "Lebanon"),
212 (LC, "Saint Lucia"),
213 (LI, "Liechtenstein"),
214 (LK, "Sri Lanka"),
215 (LR, "Liberia"),
216 (LS, "Lesotho"),
217 (LT, "Lithuania"),
218 (LU, "Luxembourg"),
219 (LV, "Latvia"),
220 (LY, "Libya"),
221 (MA, "Morocco"),
222 (MC, "Monaco"),
223 (MD, "Moldova"),
224 (ME, "Montenegro"),
225 (MF, "Saint Martin"),
226 (MG, "Madagascar"),
227 (MH, "Marshall Islands"),
228 (MK, "Macedonia"),
229 (ML, "Mali"),
230 (MM, "Myanmar"),
231 (MN, "Mongolia"),
232 (MO, "Macau"),
233 (MP, "Northern Mariana Islands"),
234 (MQ, "Martinique"),
235 (MR, "Mauritania"),
236 (MS, "Montserrat"),
237 (MT, "Malta"),
238 (MU, "Mauritius"),
239 (MV, "Maldives"),
240 (MW, "Malawi"),
241 (MX, "Mexico"),
242 (MY, "Malaysia"),
243 (MZ, "Mozambique"),
244 (NA, "Namibia"),
245 (NC, "New Caledonia"),
246 (NE, "Niger"),
247 (NF, "Norfolk Island"),
248 (NG, "Nigeria"),
249 (NI, "Nicaragua"),
250 (NL, "Netherlands"),
251 (NO, "Norway"),
252 (NP, "Nepal"),
253 (NR, "Nauru"),
254 (NU, "Niue"),
255 (NZ, "New Zealand"),
256 (OM, "Oman"),
257 (PA, "Panama"),
258 (PE, "Peru"),
259 (PF, "French Polynesia"),
260 (PG, "Papua New Guinea"),
261 (PH, "Philippines"),
262 (PK, "Pakistan"),
263 (PL, "Poland"),
264 (PM, "Saint Pierre and Miquelon"),
265 (PN, "Pitcairn"),
266 (PR, "Puerto Rico"),
267 (PS, "Palestine"),
268 (PT, "Portugal"),
269 (PW, "Palau"),
270 (PY, "Paraguay"),
271 (QA, "Qatar"),
272 (RE, "Réunion"),
273 (RO, "Romania"),
274 (RS, "Serbia"),
275 (RU, "Russia"),
276 (RW, "Rwanda"),
277 (SA, "Saudi Arabia"),
278 (SB, "Solomon Islands"),
279 (SC, "Seychelles"),
280 (SD, "Sudan"),
281 (SE, "Sweden"),
282 (SG, "Singapore"),
283 (SH, "Saint Helena, Ascension and Tristan da Cunha"),
284 (SI, "Slovenia"),
285 (SJ, "Svalbard and Jan Mayen"),
286 (SK, "Slovakia"),
287 (SL, "Sierra Leone"),
288 (SM, "San Marino"),
289 (SN, "Senegal"),
290 (SO, "Somalia"),
291 (SR, "Suriname"),
292 (SS, "South Sudan"),
293 (ST, "São Tomé and Príncipe"),
294 (SV, "El Salvador"),
295 (SX, "Sint Maarten"),
296 (SY, "Syria"),
297 (SZ, "Swaziland"),
298 (TC, "Turks and Caicos Islands"),
299 (TD, "Chad"),
300 (TF, "French Southern Territories"),
301 (TG, "Togo"),
302 (TH, "Thailand"),
303 (TJ, "Tajikistan"),
304 (TK, "Tokelau"),
305 (TL, "Timor-Leste"),
306 (TM, "Turkmenistan"),
307 (TN, "Tunisia"),
308 (TO, "Tonga"),
309 (TR, "Turkey"),
310 (TT, "Trinidad and Tobago"),
311 (TV, "Tuvalu"),
312 (TW, "Taiwan"),
313 (TZ, "Tanzania"),
314 (UA, "Ukraine"),
315 (UG, "Uganda"),
316 (UM, "United States Minor Outlying Islands"),
317 (US, "United States"),
318 (UY, "Uruguay"),
319 (UZ, "Uzbekistan"),
320 (VA, "Vatican City"),
321 (VC, "Saint Vincent and the Grenadines"),
322 (VE, "Venezuela"),
323 (VG, "British Virgin Islands"),
324 (VI, "US Virgin Islands"),
325 (VN, "Vietnam"),
326 (VU, "Vanuatu"),
327 (WF, "Wallis and Futuna"),
328 (WS, "Samoa"),
329 (XK, "Kosovo"),
330 (YE, "Yemen"),
331 (YT, "Mayotte"),
332 (ZA, "South Africa"),
333 (ZM, "Zambia"),
334 (ZW, "Zimbabwe"),
335}
336
337#[cfg(test)]
338mod tests {
339 use super::*;
340
341 #[test]
342 fn name() {
343 assert_eq!(CountryCode::AR.name(), "Argentina");
344 }
345
346 #[test]
347 fn from_str() {
348 assert_eq!(
349 "AR".parse::<CountryCode>().unwrap(),
350 CountryCode::AR,
351 "uppercase"
352 );
353 assert_eq!(
354 "ar".parse::<CountryCode>().unwrap(),
355 CountryCode::AR,
356 "lowercase"
357 );
358 assert!("bad".parse::<CountryCode>().is_err(), "error");
359 }
360
361 #[test]
362 fn into_static_str() {
363 assert_eq!(<&'static str>::from(CountryCode::AR), "AR");
364 }
365
366 #[test]
367 fn as_ref_str() {
368 assert_eq!(CountryCode::AR.as_ref(), "AR");
369 }
370
371 #[test]
372 fn display() {
373 assert_eq!(CountryCode::AR.to_string(), "AR");
374 }
375
376 #[test]
377 fn all_count() {
378 let mut all: Vec<_> = CountryCode::ALL.iter().collect();
379 all.sort();
380 all.dedup();
381 assert_eq!(all.len(), 250);
382 }
383
384 #[test]
385 fn iter() {
386 assert_eq!(
387 CountryCode::iter().next().unwrap(),
388 CountryCode::AD,
389 "first"
390 );
391 assert_eq!(CountryCode::iter().count(), 250, "count");
392 }
393}