1use core::str::FromStr;
4
5#[cfg(feature = "alloc")]
6use alloc::{
7 borrow::Cow,
8 string::{String, ToString},
9};
10
11#[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 UnitedArabEmirates,
20
21 Argentina,
23
24 Australia,
26
27 Brazil,
29
30 Canada,
32
33 Switzerland,
35
36 China,
38
39 Germany,
41
42 Egypt,
44
45 Spain,
47
48 Finland,
50
51 France,
53
54 UnitedKingdom,
56
57 Greece,
59
60 India,
62
63 Italy,
65
66 Japan,
68
69 SouthKorea,
71
72 Mexico,
74
75 Netherlands,
77
78 Norway,
80
81 NewZealand,
83
84 Poland,
86
87 SaudiArabia,
89
90 Sweden,
92
93 Singapore,
95
96 Turkey,
98
99 Ukraine,
101
102 #[default]
104 UnitedStates,
105
106 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}