macro_rules! international_currency_symbol {
() => {
"\u{00A4}"
};
}
#[allow(private_bounds)]
pub trait Currency: Sealed {
fn code(self) -> &'static str;
fn name(self) -> &'static str;
fn numeric(self) -> u16;
#[doc = concat!(
"Returns the commonly used symbol of the currency. If there is no symbol associated, the international currency symbol `",
international_currency_symbol!(),
"` is returned"
)]
fn symbol(self) -> &'static str;
}
trait Sealed {}
macro_rules! define_currency {
(
$currency:ident,
$code:literal,
$name:literal,
$numeric:literal
$(,)?
) => {
#[doc = concat!($name, " (", international_currency_symbol!(), ")")]
#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct $currency;
impl $currency {
const CODE: &'static str = $code;
const NAME: &'static str = $name;
const NUMERIC: u16 = $numeric;
const SYMBOL: &'static str = international_currency_symbol!();
}
impl Currency for $currency {
#[doc = concat!("Returns", " `", $code, "`")]
fn code(self) -> &'static str {
Self::CODE
}
#[doc = concat!("Returns", " `", $name, "`")]
fn name(self) -> &'static str {
Self::NAME
}
#[doc = concat!("Returns", " `", $numeric, "`")]
fn numeric(self) -> u16 {
Self::NUMERIC
}
#[doc = concat!("Returns", " `", international_currency_symbol!(), "`")]
fn symbol(self) -> &'static str {
Self::SYMBOL
}
}
impl Sealed for $currency {}
};
(
$currency:ident,
$code:literal,
$name:literal,
$numeric:literal,
$symbol:literal
$(,)?
) => {
#[doc = concat!($name, " (", $symbol, ")")]
#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct $currency;
impl $currency {
const CODE: &'static str = $code;
const NAME: &'static str = $name;
const NUMERIC: u16 = $numeric;
const SYMBOL: &'static str = $symbol;
}
impl Currency for $currency {
#[doc = concat!("Returns", " `", $code, "`")]
fn code(self) -> &'static str {
Self::CODE
}
#[doc = concat!("Returns", " `", $name, "`")]
fn name(self) -> &'static str {
Self::NAME
}
#[doc = concat!("Returns", " `", $numeric, "`")]
fn numeric(self) -> u16 {
Self::NUMERIC
}
#[doc = concat!("Returns", " `", $symbol, "`")]
fn symbol(self) -> &'static str {
Self::SYMBOL
}
}
impl Sealed for $currency {}
};
}
define_currency!(AUD, "AUD", "Australian dollar", 036, "\u{0024}");
define_currency!(BOV, "BOV", "Bolivian Mvdol", 984);
define_currency!(CAD, "CAD", "Canadian dollar", 124, "\u{0024}");
define_currency!(CHF, "CHF", "Swiss franc", 756);
define_currency!(CNY, "CNY", "Renminbi", 156, "\u{00A5}");
define_currency!(EUR, "EUR", "Euro", 978, "\u{20AC}");
define_currency!(GBP, "GBP", "Pound sterling", 826, "\u{00A3}");
define_currency!(HKD, "HKD", "Hong Kong dollar", 344, "\u{0024}");
define_currency!(INR, "INR", "Indian rupee", 356, "\u{20B9}");
define_currency!(JPY, "JPY", "Japanese yen", 392, "\u{00A5}");
define_currency!(KRW, "KRW", "South Korean won", 410, "\u{20A9}");
define_currency!(MXN, "MXN", "Mexican peso", 484, "\u{0024}");
define_currency!(NOK, "NOK", "Norwegian krone", 578);
define_currency!(NZD, "NZD", "New Zealand dollar", 554, "\u{0024}");
define_currency!(SEK, "SEK", "Swedish krona", 752);
define_currency!(SGD, "SGD", "Singapore dollar", 702, "\u{0024}");
define_currency!(USD, "USD", "United States dollar", 840, "\u{0024}");
#[cfg(test)]
mod tests {
use super::Currency;
use super::{BOV, USD};
#[test]
fn has_code_name_numeric_and_international_currency_symbol() {
let currency = BOV;
assert_eq!(currency.code(), "BOV");
assert_eq!(currency.name(), "Bolivian Mvdol");
assert_eq!(currency.numeric(), 984);
assert_eq!(currency.symbol(), "¤");
}
#[test]
fn has_code_name_numeric_symbol() {
let currency = USD;
assert_eq!(currency.code(), "USD");
assert_eq!(currency.name(), "United States dollar");
assert_eq!(currency.numeric(), 840);
assert_eq!(currency.symbol(), "$");
}
}