countries_tools/
lib.rs

1#![doc = include_str!("../README.md")]
2
3#![forbid(unsafe_code)]
4#![no_std]
5
6#[cfg(feature = "short-names")]
7use core::fmt;
8
9mod countries;
10#[cfg(feature = "short-names")]
11mod countries_short_names;
12
13pub use countries::{CountryAlpha2, CountryAlpha3};
14
15/// A country in the list of countries defined by ISO 3166-1.
16/// 
17/// # Examples
18/// 
19/// ```
20/// use countries_tools::{Country, CountryAlpha2};
21/// 
22/// let united_states = Country::from(CountryAlpha2::US);
23/// println!("{} is in North America.", united_states);
24/// // Prints "United States of America is in North America."
25/// 
26/// assert_eq!(united_states.short_name(), "United States of America");
27/// ```
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
29pub struct Country {
30    alpha2: CountryAlpha2,
31    alpha3: CountryAlpha3,
32    numeric: u16,
33}
34
35impl Country {
36    // No need to make this public, since countries are created by this crate only.
37    #[inline]
38    const fn new(
39        alpha2: CountryAlpha2,
40        alpha3: CountryAlpha3,
41        numeric: u16,
42        // NOTE: short name is not part of the struct as &'static str size is 16 bytes
43        //         and that would make the struct 24 bytes, making the cache of the CPU
44        //         less efficient. Instead alpha2 code enum is used as offset to get the
45        //         short name from the array of short names. That make the struct 4 bytes
46        //         and the cache of the CPU more efficient.
47        //
48        //       This has been measured with criterion before and the results show an speed
49        //         improvement of 47.21%-61.14% when searching for a country by numeric code,
50        //         and 0.15%-87.35% when searching for a country by alpha2 or alpha3 code.
51    ) -> Self {
52        Self {
53            alpha2,
54            alpha3,
55            numeric,
56        }
57    }
58
59    #[inline]
60    pub const fn alpha2(&self) -> CountryAlpha2 {
61        self.alpha2
62    }
63
64    #[inline]
65    pub const fn alpha3(&self) -> CountryAlpha3 {
66        self.alpha3
67    }
68
69    #[inline]
70    pub const fn numeric(&self) -> u16 {
71        self.numeric
72    }
73
74    #[cfg(feature = "short-names")]
75    #[inline]
76    pub const fn short_name(&self) -> &'static str {
77        countries_short_names::short_name_from_alpha2(self.alpha2)
78    }
79}
80
81#[cfg(feature = "short-names")]
82impl fmt::Display for Country {
83    #[inline]
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        self.short_name().fmt(f)
86    }
87}