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