Skip to main content

known_countries/
country.rs

1// This is free and unencumbered software released into the public domain.
2
3use core::str::FromStr;
4
5#[cfg(feature = "alloc")]
6use alloc::{
7    borrow::Cow,
8    string::{String, ToString},
9};
10
11/// A country (based on ISO 3166-1).
12#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
13#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15#[non_exhaustive]
16pub enum Country {
17
18    /// United Arab Emirates ("ae" in ISO 3166-1)
19    UnitedArabEmirates,
20
21    /// Argentina ("ar" in ISO 3166-1)
22    Argentina,
23
24    /// Australia ("au" in ISO 3166-1)
25    Australia,
26
27    /// Brazil ("br" in ISO 3166-1)
28    Brazil,
29
30    /// Canada ("ca" in ISO 3166-1)
31    Canada,
32
33    /// Switzerland ("ch" in ISO 3166-1)
34    Switzerland,
35
36    /// China ("cn" in ISO 3166-1)
37    China,
38
39    /// Germany ("de" in ISO 3166-1)
40    Germany,
41
42    /// Egypt ("eg" in ISO 3166-1)
43    Egypt,
44
45    /// Spain ("es" in ISO 3166-1)
46    Spain,
47
48    /// Finland ("fi" in ISO 3166-1)
49    Finland,
50
51    /// France ("fr" in ISO 3166-1)
52    France,
53
54    /// United Kingdom ("gb" in ISO 3166-1)
55    UnitedKingdom,
56
57    /// Greece ("gr" in ISO 3166-1)
58    Greece,
59
60    /// India ("in" in ISO 3166-1)
61    India,
62
63    /// Italy ("it" in ISO 3166-1)
64    Italy,
65
66    /// Japan ("jp" in ISO 3166-1)
67    Japan,
68
69    /// South Korea ("kr" in ISO 3166-1)
70    SouthKorea,
71
72    /// Mexico ("mx" in ISO 3166-1)
73    Mexico,
74
75    /// Netherlands ("nl" in ISO 3166-1)
76    Netherlands,
77
78    /// Norway ("no" in ISO 3166-1)
79    Norway,
80
81    /// New Zealand ("nz" in ISO 3166-1)
82    NewZealand,
83
84    /// Poland ("pl" in ISO 3166-1)
85    Poland,
86
87    /// Saudi Arabia ("sa" in ISO 3166-1)
88    SaudiArabia,
89
90    /// Sweden ("se" in ISO 3166-1)
91    Sweden,
92
93    /// Singapore ("sg" in ISO 3166-1)
94    Singapore,
95
96    /// Turkey ("tr" in ISO 3166-1)
97    Turkey,
98
99    /// Ukraine ("ua" in ISO 3166-1)
100    Ukraine,
101
102    /// United States ("us" in ISO 3166-1)
103    #[default]
104    UnitedStates,
105
106    /// South Africa ("za" in ISO 3166-1)
107    SouthAfrica,
108
109    #[cfg(feature = "alloc")]
110    Other(String),
111}
112
113impl Country {
114    pub const ALL: &'static [Self] = &[];
115
116    pub fn as_str(&self) -> &str {
117        use Country::*;
118        match self {
119            UnitedArabEmirates => "ae",
120            Argentina => "ar",
121            Australia => "au",
122            Brazil => "br",
123            Canada => "ca",
124            Switzerland => "ch",
125            China => "cn",
126            Germany => "de",
127            Egypt => "eg",
128            Spain => "es",
129            Finland => "fi",
130            France => "fr",
131            UnitedKingdom => "gb",
132            Greece => "gr",
133            India => "in",
134            Italy => "it",
135            Japan => "jp",
136            SouthKorea => "kr",
137            Mexico => "mx",
138            Netherlands => "nl",
139            Norway => "no",
140            NewZealand => "nz",
141            Poland => "pl",
142            SaudiArabia => "sa",
143            Sweden => "se",
144            Singapore => "sg",
145            Turkey => "tr",
146            Ukraine => "ua",
147            UnitedStates => "us",
148            SouthAfrica => "za",
149
150            #[cfg(feature = "alloc")]
151            Other(input) => input.as_str(),
152        }
153    }
154
155    #[cfg(feature = "alloc")]
156    pub fn into_string(self) -> String {
157        self.as_str().into()
158    }
159
160    #[cfg(all(feature = "serde", feature = "alloc"))]
161    pub fn to_json(&self) -> Option<serde_json::Value> {
162        Some(self.clone().into_json())
163    }
164
165    #[cfg(all(feature = "serde", feature = "alloc"))]
166    pub fn into_json(self) -> serde_json::Value {
167        serde_json::Value::String(self.into_string())
168    }
169
170    #[cfg(all(feature = "bson", feature = "alloc"))]
171    pub fn to_bson(&self) -> Option<bson::Bson> {
172        Some(self.clone().into_bson())
173    }
174
175    #[cfg(all(feature = "bson", feature = "alloc"))]
176    pub fn into_bson(self) -> bson::Bson {
177        bson::Bson::String(self.into_string())
178    }
179}
180
181impl FromStr for Country {
182    type Err = ();
183
184    fn from_str(input: &str) -> Result<Self, Self::Err> {
185        use Country::*;
186        Ok(match input {
187            "ae" => UnitedArabEmirates,
188            "ar" => Argentina,
189            "au" => Australia,
190            "br" => Brazil,
191            "ca" => Canada,
192            "ch" => Switzerland,
193            "cn" => China,
194            "de" => Germany,
195            "eg" => Egypt,
196            "es" => Spain,
197            "fi" => Finland,
198            "fr" => France,
199            "gb" => UnitedKingdom,
200            "gr" => Greece,
201            "in" => India,
202            "it" => Italy,
203            "jp" => Japan,
204            "kr" => SouthKorea,
205            "mx" => Mexico,
206            "nl" => Netherlands,
207            "no" => Norway,
208            "nz" => NewZealand,
209            "pl" => Poland,
210            "sa" => SaudiArabia,
211            "se" => Sweden,
212            "sg" => Singapore,
213            "tr" => Turkey,
214            "ua" => Ukraine,
215            "us" => UnitedStates,
216            "za" => SouthAfrica,
217            _ => return Err(()),
218        })
219    }
220}
221
222impl core::fmt::Display for Country {
223    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
224        write!(f, "{}", self.as_str())
225    }
226}
227
228impl AsRef<str> for Country {
229    fn as_ref(&self) -> &str {
230        self.as_str()
231    }
232}
233
234impl<T> From<&T> for Country
235where
236    T: Clone + Into<Self>,
237{
238    fn from(t: &T) -> Self {
239        t.clone().into()
240    }
241}
242
243impl From<&str> for Country {
244    fn from(input: &str) -> Self {
245        match input.parse() {
246            Ok(output) => output,
247
248            #[cfg(feature = "alloc")]
249            Err(_) => Self::Other(input.into()),
250
251            #[cfg(not(feature = "alloc"))]
252            Err(_) => unimplemented!("unknown country: {}", input),
253        }
254    }
255}
256
257#[cfg(feature = "alloc")]
258impl<'a> From<Cow<'a, str>> for Country {
259    fn from(input: Cow<'a, str>) -> Self {
260        input
261            .parse()
262            .unwrap_or_else(|_| Self::Other(input.into_owned()))
263    }
264}
265
266#[cfg(feature = "alloc")]
267impl From<String> for Country {
268    fn from(input: String) -> Self {
269        input.parse().unwrap_or_else(|_| Self::Other(input))
270    }
271}
272
273#[cfg(all(feature = "serde", feature = "alloc"))]
274impl TryFrom<serde_json::Value> for Country {
275    type Error = ();
276
277    fn try_from(input: serde_json::Value) -> Result<Self, Self::Error> {
278        use serde_json::Value;
279        match input {
280            Value::String(input) => Ok(input.parse().unwrap_or_else(|_| Self::Other(input))),
281            _ => Err(()),
282        }
283    }
284}
285
286impl From<&'static Country> for &str {
287    fn from(input: &'static Country) -> Self {
288        input.as_str()
289    }
290}
291
292#[cfg(feature = "alloc")]
293impl From<Country> for String {
294    fn from(input: Country) -> Self {
295        input.to_string()
296    }
297}