1#![no_std]
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6pub const UNKNOWN_CODE: &str = "XX";
8
9pub const UNKNOWN: &str = "Unknown";
11
12#[derive(Clone, Copy, Debug)]
24#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
25pub struct Country {
26 pub code: &'static str,
27 pub name: &'static str,
28}
29
30impl Default for Country {
32 fn default() -> Self {
33 Self {
34 code: UNKNOWN_CODE,
35 name: UNKNOWN,
36 }
37 }
38}
39
40const _: () = {
41 let mut i = 0;
42 while i < COUNTRIES_DATA.len() - 1 {
43 let a = COUNTRIES_DATA[i].code.as_bytes();
44 let b = COUNTRIES_DATA[i + 1].code.as_bytes();
45 assert!(a.len() == 2 && b.len() == 2);
46 let a_val = (a[0] as u16) << 8 | a[1] as u16;
47 let b_val = (b[0] as u16) << 8 | b[1] as u16;
48 assert!(a_val < b_val);
49 i += 1;
50 }
51};
52
53pub const fn countries() -> &'static [Country] {
63 COUNTRIES_DATA
64}
65
66pub const fn name(code: &str) -> &'static str {
79 let code = code.as_bytes();
84 if code.len() != 2 {
85 return UNKNOWN;
86 }
87 let needle = (code[0] as u16) << 8 | code[1] as u16;
88 let mut lo = 0usize;
89 let mut hi = COUNTRIES_DATA.len();
90 while lo < hi {
91 let mid = lo + (hi - lo) / 2;
92 let entry = COUNTRIES_DATA[mid].code.as_bytes();
93 let mid_val = (entry[0] as u16) << 8 | entry[1] as u16;
94 if needle < mid_val {
95 hi = mid;
96 } else if needle > mid_val {
97 lo = mid + 1;
98 } else {
99 return COUNTRIES_DATA[mid].name;
100 }
101 }
102 UNKNOWN
103}
104
105const COUNTRIES_DATA: &[Country] = &[
106 Country {
107 code: "AD",
108 name: "AndorrA",
109 },
110 Country {
111 code: "AE",
112 name: "United Arab Emirates",
113 },
114 Country {
115 code: "AF",
116 name: "Afghanistan",
117 },
118 Country {
119 code: "AG",
120 name: "Antigua and Barbuda",
121 },
122 Country {
123 code: "AI",
124 name: "Anguilla",
125 },
126 Country {
127 code: "AL",
128 name: "Albania",
129 },
130 Country {
131 code: "AM",
132 name: "Armenia",
133 },
134 Country {
135 code: "AN",
136 name: "Netherlands Antilles",
137 },
138 Country {
139 code: "AO",
140 name: "Angola",
141 },
142 Country {
143 code: "AQ",
144 name: "Antarctica",
145 },
146 Country {
147 code: "AR",
148 name: "Argentina",
149 },
150 Country {
151 code: "AS",
152 name: "American Samoa",
153 },
154 Country {
155 code: "AT",
156 name: "Austria",
157 },
158 Country {
159 code: "AU",
160 name: "Australia",
161 },
162 Country {
163 code: "AW",
164 name: "Aruba",
165 },
166 Country {
167 code: "AX",
168 name: "Åland Islands",
169 },
170 Country {
171 code: "AZ",
172 name: "Azerbaijan",
173 },
174 Country {
175 code: "BA",
176 name: "Bosnia and Herzegovina",
177 },
178 Country {
179 code: "BB",
180 name: "Barbados",
181 },
182 Country {
183 code: "BD",
184 name: "Bangladesh",
185 },
186 Country {
187 code: "BE",
188 name: "Belgium",
189 },
190 Country {
191 code: "BF",
192 name: "Burkina Faso",
193 },
194 Country {
195 code: "BG",
196 name: "Bulgaria",
197 },
198 Country {
199 code: "BH",
200 name: "Bahrain",
201 },
202 Country {
203 code: "BI",
204 name: "Burundi",
205 },
206 Country {
207 code: "BJ",
208 name: "Benin",
209 },
210 Country {
211 code: "BL",
212 name: "Saint Barthélemy",
213 },
214 Country {
215 code: "BM",
216 name: "Bermuda",
217 },
218 Country {
219 code: "BN",
220 name: "Brunei Darussalam",
221 },
222 Country {
223 code: "BO",
224 name: "Bolivia",
225 },
226 Country {
227 code: "BQ",
228 name: "Bonaire, Sint Eustatius and Saba",
229 },
230 Country {
231 code: "BR",
232 name: "Brazil",
233 },
234 Country {
235 code: "BS",
236 name: "Bahamas",
237 },
238 Country {
239 code: "BT",
240 name: "Bhutan",
241 },
242 Country {
243 code: "BV",
244 name: "Bouvet Island",
245 },
246 Country {
247 code: "BW",
248 name: "Botswana",
249 },
250 Country {
251 code: "BY",
252 name: "Belarus",
253 },
254 Country {
255 code: "BZ",
256 name: "Belize",
257 },
258 Country {
259 code: "CA",
260 name: "Canada",
261 },
262 Country {
263 code: "CC",
264 name: "Cocos (Keeling) Islands",
265 },
266 Country {
267 code: "CD",
268 name: "Congo, The Democratic Republic of the",
269 },
270 Country {
271 code: "CF",
272 name: "Central African Republic",
273 },
274 Country {
275 code: "CG",
276 name: "Congo",
277 },
278 Country {
279 code: "CH",
280 name: "Switzerland",
281 },
282 Country {
283 code: "CI",
284 name: "Cote D'Ivoire",
285 },
286 Country {
287 code: "CK",
288 name: "Cook Islands",
289 },
290 Country {
291 code: "CL",
292 name: "Chile",
293 },
294 Country {
295 code: "CM",
296 name: "Cameroon",
297 },
298 Country {
299 code: "CN",
300 name: "China",
301 },
302 Country {
303 code: "CO",
304 name: "Colombia",
305 },
306 Country {
307 code: "CR",
308 name: "Costa Rica",
309 },
310 Country {
311 code: "CU",
312 name: "Cuba",
313 },
314 Country {
315 code: "CV",
316 name: "Cape Verde",
317 },
318 Country {
319 code: "CW",
320 name: "Curacao",
321 },
322 Country {
323 code: "CX",
324 name: "Christmas Island",
325 },
326 Country {
327 code: "CY",
328 name: "Cyprus",
329 },
330 Country {
331 code: "CZ",
332 name: "Czech Republic",
333 },
334 Country {
335 code: "DE",
336 name: "Germany",
337 },
338 Country {
339 code: "DJ",
340 name: "Djibouti",
341 },
342 Country {
343 code: "DK",
344 name: "Denmark",
345 },
346 Country {
347 code: "DM",
348 name: "Dominica",
349 },
350 Country {
351 code: "DO",
352 name: "Dominican Republic",
353 },
354 Country {
355 code: "DZ",
356 name: "Algeria",
357 },
358 Country {
359 code: "EC",
360 name: "Ecuador",
361 },
362 Country {
363 code: "EE",
364 name: "Estonia",
365 },
366 Country {
367 code: "EG",
368 name: "Egypt",
369 },
370 Country {
371 code: "EH",
372 name: "Western Sahara",
373 },
374 Country {
375 code: "ER",
376 name: "Eritrea",
377 },
378 Country {
379 code: "ES",
380 name: "Spain",
381 },
382 Country {
383 code: "ET",
384 name: "Ethiopia",
385 },
386 Country {
387 code: "FI",
388 name: "Finland",
389 },
390 Country {
391 code: "FJ",
392 name: "Fiji",
393 },
394 Country {
395 code: "FK",
396 name: "Falkland Islands (Malvinas)",
397 },
398 Country {
399 code: "FM",
400 name: "Micronesia, Federated States of",
401 },
402 Country {
403 code: "FO",
404 name: "Faroe Islands",
405 },
406 Country {
407 code: "FR",
408 name: "France",
409 },
410 Country {
411 code: "GA",
412 name: "Gabon",
413 },
414 Country {
415 code: "GB",
416 name: "United Kingdom",
417 },
418 Country {
419 code: "GD",
420 name: "Grenada",
421 },
422 Country {
423 code: "GE",
424 name: "Georgia",
425 },
426 Country {
427 code: "GF",
428 name: "French Guiana",
429 },
430 Country {
431 code: "GG",
432 name: "Guernsey",
433 },
434 Country {
435 code: "GH",
436 name: "Ghana",
437 },
438 Country {
439 code: "GI",
440 name: "Gibraltar",
441 },
442 Country {
443 code: "GL",
444 name: "Greenland",
445 },
446 Country {
447 code: "GM",
448 name: "Gambia",
449 },
450 Country {
451 code: "GN",
452 name: "Guinea",
453 },
454 Country {
455 code: "GP",
456 name: "Guadeloupe",
457 },
458 Country {
459 code: "GQ",
460 name: "Equatorial Guinea",
461 },
462 Country {
463 code: "GR",
464 name: "Greece",
465 },
466 Country {
467 code: "GS",
468 name: "South Georgia and the South Sandwich Islands",
469 },
470 Country {
471 code: "GT",
472 name: "Guatemala",
473 },
474 Country {
475 code: "GU",
476 name: "Guam",
477 },
478 Country {
479 code: "GW",
480 name: "Guinea-Bissau",
481 },
482 Country {
483 code: "GY",
484 name: "Guyana",
485 },
486 Country {
487 code: "HK",
488 name: "Hong Kong",
489 },
490 Country {
491 code: "HM",
492 name: "Heard Island and Mcdonald Islands",
493 },
494 Country {
495 code: "HN",
496 name: "Honduras",
497 },
498 Country {
499 code: "HR",
500 name: "Croatia",
501 },
502 Country {
503 code: "HT",
504 name: "Haiti",
505 },
506 Country {
507 code: "HU",
508 name: "Hungary",
509 },
510 Country {
511 code: "ID",
512 name: "Indonesia",
513 },
514 Country {
515 code: "IE",
516 name: "Ireland",
517 },
518 Country {
519 code: "IL",
520 name: "Israel",
521 },
522 Country {
523 code: "IM",
524 name: "Isle of Man",
525 },
526 Country {
527 code: "IN",
528 name: "India",
529 },
530 Country {
531 code: "IO",
532 name: "British Indian Ocean Territory",
533 },
534 Country {
535 code: "IQ",
536 name: "Iraq",
537 },
538 Country {
539 code: "IR",
540 name: "Iran, Islamic Republic Of",
541 },
542 Country {
543 code: "IS",
544 name: "Iceland",
545 },
546 Country {
547 code: "IT",
548 name: "Italy",
549 },
550 Country {
551 code: "JE",
552 name: "Jersey",
553 },
554 Country {
555 code: "JM",
556 name: "Jamaica",
557 },
558 Country {
559 code: "JO",
560 name: "Jordan",
561 },
562 Country {
563 code: "JP",
564 name: "Japan",
565 },
566 Country {
567 code: "KE",
568 name: "Kenya",
569 },
570 Country {
571 code: "KG",
572 name: "Kyrgyzstan",
573 },
574 Country {
575 code: "KH",
576 name: "Cambodia",
577 },
578 Country {
579 code: "KI",
580 name: "Kiribati",
581 },
582 Country {
583 code: "KM",
584 name: "Comoros",
585 },
586 Country {
587 code: "KN",
588 name: "Saint Kitts and Nevis",
589 },
590 Country {
591 code: "KP",
592 name: "Korea, Democratic People's Republic of",
593 },
594 Country {
595 code: "KR",
596 name: "Korea, Republic of",
597 },
598 Country {
599 code: "KW",
600 name: "Kuwait",
601 },
602 Country {
603 code: "KY",
604 name: "Cayman Islands",
605 },
606 Country {
607 code: "KZ",
608 name: "Kazakhstan",
609 },
610 Country {
611 code: "LA",
612 name: "Lao People's Democratic Republic",
613 },
614 Country {
615 code: "LB",
616 name: "Lebanon",
617 },
618 Country {
619 code: "LC",
620 name: "Saint Lucia",
621 },
622 Country {
623 code: "LI",
624 name: "Liechtenstein",
625 },
626 Country {
627 code: "LK",
628 name: "Sri Lanka",
629 },
630 Country {
631 code: "LR",
632 name: "Liberia",
633 },
634 Country {
635 code: "LS",
636 name: "Lesotho",
637 },
638 Country {
639 code: "LT",
640 name: "Lithuania",
641 },
642 Country {
643 code: "LU",
644 name: "Luxembourg",
645 },
646 Country {
647 code: "LV",
648 name: "Latvia",
649 },
650 Country {
651 code: "LY",
652 name: "Libyan Arab Jamahiriya",
653 },
654 Country {
655 code: "MA",
656 name: "Morocco",
657 },
658 Country {
659 code: "MC",
660 name: "Monaco",
661 },
662 Country {
663 code: "MD",
664 name: "Moldova, Republic of",
665 },
666 Country {
667 code: "ME",
668 name: "Montenegro",
669 },
670 Country {
671 code: "MF",
672 name: "Saint Martin",
673 },
674 Country {
675 code: "MG",
676 name: "Madagascar",
677 },
678 Country {
679 code: "MH",
680 name: "Marshall Islands",
681 },
682 Country {
683 code: "MK",
684 name: "North Macedonia",
685 },
686 Country {
687 code: "ML",
688 name: "Mali",
689 },
690 Country {
691 code: "MM",
692 name: "Myanmar",
693 },
694 Country {
695 code: "MN",
696 name: "Mongolia",
697 },
698 Country {
699 code: "MO",
700 name: "Macao",
701 },
702 Country {
703 code: "MP",
704 name: "Northern Mariana Islands",
705 },
706 Country {
707 code: "MQ",
708 name: "Martinique",
709 },
710 Country {
711 code: "MR",
712 name: "Mauritania",
713 },
714 Country {
715 code: "MS",
716 name: "Montserrat",
717 },
718 Country {
719 code: "MT",
720 name: "Malta",
721 },
722 Country {
723 code: "MU",
724 name: "Mauritius",
725 },
726 Country {
727 code: "MV",
728 name: "Maldives",
729 },
730 Country {
731 code: "MW",
732 name: "Malawi",
733 },
734 Country {
735 code: "MX",
736 name: "Mexico",
737 },
738 Country {
739 code: "MY",
740 name: "Malaysia",
741 },
742 Country {
743 code: "MZ",
744 name: "Mozambique",
745 },
746 Country {
747 code: "NA",
748 name: "Namibia",
749 },
750 Country {
751 code: "NC",
752 name: "New Caledonia",
753 },
754 Country {
755 code: "NE",
756 name: "Niger",
757 },
758 Country {
759 code: "NF",
760 name: "Norfolk Island",
761 },
762 Country {
763 code: "NG",
764 name: "Nigeria",
765 },
766 Country {
767 code: "NI",
768 name: "Nicaragua",
769 },
770 Country {
771 code: "NL",
772 name: "Netherlands",
773 },
774 Country {
775 code: "NO",
776 name: "Norway",
777 },
778 Country {
779 code: "NP",
780 name: "Nepal",
781 },
782 Country {
783 code: "NR",
784 name: "Nauru",
785 },
786 Country {
787 code: "NU",
788 name: "Niue",
789 },
790 Country {
791 code: "NZ",
792 name: "New Zealand",
793 },
794 Country {
795 code: "OM",
796 name: "Oman",
797 },
798 Country {
799 code: "PA",
800 name: "Panama",
801 },
802 Country {
803 code: "PE",
804 name: "Peru",
805 },
806 Country {
807 code: "PF",
808 name: "French Polynesia",
809 },
810 Country {
811 code: "PG",
812 name: "Papua New Guinea",
813 },
814 Country {
815 code: "PH",
816 name: "Philippines",
817 },
818 Country {
819 code: "PK",
820 name: "Pakistan",
821 },
822 Country {
823 code: "PL",
824 name: "Poland",
825 },
826 Country {
827 code: "PM",
828 name: "Saint Pierre and Miquelon",
829 },
830 Country {
831 code: "PN",
832 name: "Pitcairn",
833 },
834 Country {
835 code: "PR",
836 name: "Puerto Rico",
837 },
838 Country {
839 code: "PS",
840 name: "Palestinian Territory, Occupied",
841 },
842 Country {
843 code: "PT",
844 name: "Portugal",
845 },
846 Country {
847 code: "PW",
848 name: "Palau",
849 },
850 Country {
851 code: "PY",
852 name: "Paraguay",
853 },
854 Country {
855 code: "QA",
856 name: "Qatar",
857 },
858 Country {
859 code: "RE",
860 name: "Reunion",
861 },
862 Country {
863 code: "RO",
864 name: "Romania",
865 },
866 Country {
867 code: "RS",
868 name: "Serbia",
869 },
870 Country {
871 code: "RU",
872 name: "Russian Federation",
873 },
874 Country {
875 code: "RW",
876 name: "Rwanda",
877 },
878 Country {
879 code: "SA",
880 name: "Saudi Arabia",
881 },
882 Country {
883 code: "SB",
884 name: "Solomon Islands",
885 },
886 Country {
887 code: "SC",
888 name: "Seychelles",
889 },
890 Country {
891 code: "SD",
892 name: "Sudan",
893 },
894 Country {
895 code: "SE",
896 name: "Sweden",
897 },
898 Country {
899 code: "SG",
900 name: "Singapore",
901 },
902 Country {
903 code: "SH",
904 name: "Saint Helena",
905 },
906 Country {
907 code: "SI",
908 name: "Slovenia",
909 },
910 Country {
911 code: "SJ",
912 name: "Svalbard and Jan Mayen",
913 },
914 Country {
915 code: "SK",
916 name: "Slovakia",
917 },
918 Country {
919 code: "SL",
920 name: "Sierra Leone",
921 },
922 Country {
923 code: "SM",
924 name: "San Marino",
925 },
926 Country {
927 code: "SN",
928 name: "Senegal",
929 },
930 Country {
931 code: "SO",
932 name: "Somalia",
933 },
934 Country {
935 code: "SR",
936 name: "Suriname",
937 },
938 Country {
939 code: "SS",
940 name: "South Sudan",
941 },
942 Country {
943 code: "ST",
944 name: "Sao Tome and Principe",
945 },
946 Country {
947 code: "SV",
948 name: "El Salvador",
949 },
950 Country {
951 code: "SX",
952 name: "Sint Maarten (Dutch part)",
953 },
954 Country {
955 code: "SY",
956 name: "Syrian Arab Republic",
957 },
958 Country {
959 code: "SZ",
960 name: "Eswatini",
961 },
962 Country {
963 code: "TC",
964 name: "Turks and Caicos Islands",
965 },
966 Country {
967 code: "TD",
968 name: "Chad",
969 },
970 Country {
971 code: "TF",
972 name: "French Southern Territories",
973 },
974 Country {
975 code: "TG",
976 name: "Togo",
977 },
978 Country {
979 code: "TH",
980 name: "Thailand",
981 },
982 Country {
983 code: "TJ",
984 name: "Tajikistan",
985 },
986 Country {
987 code: "TK",
988 name: "Tokelau",
989 },
990 Country {
991 code: "TL",
992 name: "Timor-Leste",
993 },
994 Country {
995 code: "TM",
996 name: "Turkmenistan",
997 },
998 Country {
999 code: "TN",
1000 name: "Tunisia",
1001 },
1002 Country {
1003 code: "TO",
1004 name: "Tonga",
1005 },
1006 Country {
1007 code: "TR",
1008 name: "Turkey",
1009 },
1010 Country {
1011 code: "TT",
1012 name: "Trinidad and Tobago",
1013 },
1014 Country {
1015 code: "TV",
1016 name: "Tuvalu",
1017 },
1018 Country {
1019 code: "TW",
1020 name: "Taiwan",
1021 },
1022 Country {
1023 code: "TZ",
1024 name: "Tanzania, United Republic of",
1025 },
1026 Country {
1027 code: "UA",
1028 name: "Ukraine",
1029 },
1030 Country {
1031 code: "UG",
1032 name: "Uganda",
1033 },
1034 Country {
1035 code: "UM",
1036 name: "United States Minor Outlying Islands",
1037 },
1038 Country {
1039 code: "US",
1040 name: "United States",
1041 },
1042 Country {
1043 code: "UY",
1044 name: "Uruguay",
1045 },
1046 Country {
1047 code: "UZ",
1048 name: "Uzbekistan",
1049 },
1050 Country {
1051 code: "VA",
1052 name: "Holy See (Vatican City State)",
1053 },
1054 Country {
1055 code: "VC",
1056 name: "Saint Vincent and the Grenadines",
1057 },
1058 Country {
1059 code: "VE",
1060 name: "Venezuela",
1061 },
1062 Country {
1063 code: "VG",
1064 name: "Virgin Islands, British",
1065 },
1066 Country {
1067 code: "VI",
1068 name: "Virgin Islands, U.S.",
1069 },
1070 Country {
1071 code: "VN",
1072 name: "Viet Nam",
1073 },
1074 Country {
1075 code: "VU",
1076 name: "Vanuatu",
1077 },
1078 Country {
1079 code: "WF",
1080 name: "Wallis and Futuna",
1081 },
1082 Country {
1083 code: "WS",
1084 name: "Samoa",
1085 },
1086 Country {
1087 code: "XK",
1088 name: "Kosovo",
1089 },
1090 Country {
1091 code: "YE",
1092 name: "Yemen",
1093 },
1094 Country {
1095 code: "YT",
1096 name: "Mayotte",
1097 },
1098 Country {
1099 code: "ZA",
1100 name: "South Africa",
1101 },
1102 Country {
1103 code: "ZM",
1104 name: "Zambia",
1105 },
1106 Country {
1107 code: "ZW",
1108 name: "Zimbabwe",
1109 },
1110];
1111
1112#[cfg(test)]
1113mod tests {
1114 use super::*;
1115
1116 #[test]
1117 fn known_country() {
1118 assert_eq!(name("FR"), "France");
1119 assert_eq!(name("GB"), "United Kingdom");
1120 assert_eq!(name("US"), "United States");
1121 assert_eq!(name("DE"), "Germany");
1122 }
1123
1124 #[test]
1125 fn unknown_country() {
1126 assert_eq!(name("ZZ"), "Unknown");
1127 assert_eq!(name("??"), "Unknown");
1128 }
1129
1130 #[test]
1131 fn wrong_length() {
1132 assert_eq!(name(""), "Unknown");
1133 assert_eq!(name("F"), "Unknown");
1134 assert_eq!(name("FRA"), "Unknown");
1135 }
1136
1137 #[test]
1138 fn default_country() {
1139 let c = Country::default();
1140 assert_eq!(c.code, "XX");
1141 assert_eq!(c.name, "Unknown");
1142 }
1143
1144 #[test]
1145 fn countries_slice_is_sorted() {
1146 for win in countries().windows(2) {
1147 assert!(win[0].code < win[1].code, "out of order: {} >= {}", win[0].code, win[1].code);
1148 }
1149 }
1150
1151 #[test]
1152 fn correct_entry_count() {
1153 assert_eq!(countries().len(), 251);
1154 }
1155
1156 #[test]
1157 fn round_trip_all() {
1158 for c in countries() {
1159 assert_eq!(name(c.code), c.name, "failed for {}", c.code);
1160 }
1161 }
1162}