use crate::providers::ExchangeRateProvider;
use crate::providers::LiveExchangeProvider;
use rust_decimal::Decimal;
use std::fmt;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum CurrencyUnit {
USD,
EUR,
GBP,
JPY,
}
impl CurrencyUnit {
pub fn parse(s: &str) -> Option<Self> {
match s.to_ascii_uppercase().as_str() {
"USD" => Some(Self::USD),
"EUR" => Some(Self::EUR),
"GBP" => Some(Self::GBP),
"JPY" => Some(Self::JPY),
_ => None,
}
}
pub fn as_str(&self) -> &'static str {
match self {
Self::USD => "USD",
Self::EUR => "EUR",
Self::GBP => "GBP",
Self::JPY => "JPY",
}
}
}
impl fmt::Display for CurrencyUnit {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
pub fn convert_with_provider<P: ExchangeRateProvider>(
value: Decimal,
from: CurrencyUnit,
to: CurrencyUnit,
provider: &P,
) -> Result<Decimal, String> {
let rate = provider.get_rate(from, to)?;
Ok(value * rate)
}
pub fn convert(value: Decimal, from: CurrencyUnit, to: CurrencyUnit) -> Result<Decimal, String> {
let provider = LiveExchangeProvider::new(None);
convert_with_provider(value, from, to, &provider)
}