country_code/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3pub extern crate alloc;
4
5//
6#[macro_export]
7macro_rules! country_code {
8    (
9        length = $length:tt;
10        $( #[$meta:meta] )*
11        $pub:vis enum $name:ident {
12            $(
13                $( #[$variant_meta:meta] )*
14                $variant:ident,
15            )+
16        }
17    ) => {
18        $(#[$meta])*
19        $pub enum $name {
20            $(
21                $( #[$variant_meta] )*
22                $variant,
23            )+
24            Other($crate::alloc::boxed::Box<str>),
25        }
26
27        //
28        impl $name {
29            pub const VARS: &'static [$name] = &[
30                $(
31                    $name::$variant,
32                )+
33            ];
34        }
35
36        //
37        impl ::core::str::FromStr for $name {
38            type Err = $crate::error::ParseError;
39
40            fn from_str(s: &str) -> Result<Self, Self::Err> {
41                match s {
42                    $(
43                        ::core::stringify!($variant) => Ok(Self::$variant),
44                    )+
45                    s if s.len() == $length => Ok(Self::Other(s.into())),
46                    s => Err($crate::error::ParseError::Invalid(s.into()))
47                }
48            }
49        }
50
51        //
52        impl ::core::fmt::Display for $name {
53            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
54                match self {
55                    $(
56                        Self::$variant => ::core::write!(f, "{}", ::core::stringify!($variant)),
57                    )+
58                    Self::Other(s) => ::core::write!(f, "{}", s)
59                }
60            }
61        }
62
63        //
64        impl ::core::default::Default for $name {
65            fn default() -> Self {
66                Self::Other(Default::default())
67            }
68        }
69
70        //
71        impl ::core::cmp::PartialEq for $name {
72            fn eq(&self, other: &Self) -> bool {
73                $crate::alloc::format!("{}", self) == $crate::alloc::format!("{}", other)
74            }
75        }
76
77        impl ::core::cmp::Eq for $name {
78        }
79
80        //
81        $crate::impl_partial_eq_str_for_display! { str, $name }
82        $crate::impl_partial_eq_str_for_display! { &'a str, $name }
83        $crate::impl_partial_eq_str_for_display! { $crate::alloc::borrow::Cow<'a, str>, $name }
84        $crate::impl_partial_eq_str_for_display! { $crate::alloc::string::String, $name }
85
86        //
87        #[cfg(feature = "std")]
88        impl ::std::hash::Hash for $name {
89            fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
90                $crate::alloc::format!("{}", self).hash(state);
91            }
92        }
93
94        //
95        #[cfg(feature = "serde")]
96        impl<'de> ::serde::Deserialize<'de> for $name {
97            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
98            where
99                D: ::serde::Deserializer<'de>,
100            {
101                use ::core::str::FromStr as _;
102
103                let s = $crate::alloc::boxed::Box::<str>::deserialize(deserializer)?;
104                Self::from_str(&s).map_err(::serde::de::Error::custom)
105            }
106        }
107
108        //
109        #[cfg(feature = "serde")]
110        impl ::serde::Serialize for $name {
111            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
112            where
113                S: ::serde::Serializer,
114            {
115                use $crate::alloc::string::ToString as _;
116
117                self.to_string().serialize(serializer)
118            }
119        }
120    };
121}
122
123//
124pub mod error;
125
126//
127pub mod iso3166_1;
128pub mod iso3166_2;
129
130pub use iso3166_1::alpha_2::CountryCode;
131pub use iso3166_2::SubdivisionCode;
132
133//
134#[macro_export]
135macro_rules! impl_partial_eq_str_for_display {
136    ($str:ty, $display:ty) => {
137        #[allow(unused_lifetimes)]
138        impl<'a> ::core::cmp::PartialEq<$str> for $display {
139            fn eq(&self, other: &$str) -> bool {
140                ::core::cmp::PartialEq::eq(&$crate::alloc::format!("{}", self)[..], &other[..])
141            }
142        }
143    };
144}