currency_code/
lib.rs

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