1#![cfg_attr(not(feature = "std"), no_std)]
2
3pub extern crate alloc;
4
5#[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 impl $name {
28 pub const VARS: &'static [$name] = &[
29 $(
30 Self::$variant,
31 )+
32 ];
33 }
34
35 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 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 impl ::core::default::Default for $name {
64 fn default() -> Self {
65 Self::Other(Default::default())
66 }
67 }
68
69 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 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 #[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 #[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 #[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
122pub mod error;
124
125pub mod iso4217;
127
128pub use iso4217::CurrencyCode;