pub trait Exchange<C: Currency> {
type Target<T: Currency>
where Self: Convert<T>;
// Required method
fn convert<T: Currency + Clone>(
&self,
rate: impl Rate<C, T>,
) -> Option<Self::Target<T>>
where Self: Convert<T>;
}Expand description
Trait for currency exchange. This does exchange from C into T.
This trait has blanket implementation for M where M implements BaseMoney<C> + BaseOps<C> + Convert<C>
with method convert that does the conversion.
Required Associated Types§
Required Methods§
Sourcefn convert<T: Currency + Clone>(
&self,
rate: impl Rate<C, T>,
) -> Option<Self::Target<T>>where
Self: Convert<T>,
fn convert<T: Currency + Clone>(
&self,
rate: impl Rate<C, T>,
) -> Option<Self::Target<T>>where
Self: Convert<T>,
Method to do conversion from Self<C> into Target<T>.
If C == T, immediately return Target<T> with Self’s amount.
§Arguments
- T: Currency = Target conversion currency.
- rate: Rate<C, T> = rate amount accepting these types:
Money<T>where T is target currencyRawMoney<T>where T is target currencyDecimalf64i32i64i128ExchangeRates<'a, C>where C is base currency of exchange rates
§Examples
use moneylib::{Money, RawMoney, BaseMoney, BaseOps, Exchange, ExchangeRates, Currency};
use moneylib::iso::{EUR, IDR, IRR, USD, CAD};
use moneylib::macros::dec;
let money = Money::<USD>::new(123).unwrap();
let ret = money.convert::<EUR>(dec!(0.8));
assert_eq!(ret.unwrap().amount(), dec!(98.4));
let money = Money::<USD>::new(123).unwrap();
let ret = money.convert::<USD>(2); // rate 2 will be ignored since converting to the same currency.
assert_eq!(ret.unwrap().amount(), dec!(123));
let money = Money::<USD>::from_decimal(dec!(100));
let ret = money.convert::<EUR>(0.888234);
assert_eq!(ret.unwrap().amount(), dec!(88.82));
let raw_money = RawMoney::<USD>::from_decimal(dec!(100));
let ret = raw_money.convert::<EUR>(0.8882346);
assert_eq!(ret.unwrap().amount(), dec!(88.82346));
let money = Money::<USD>::new(123).unwrap();
let mut rates = ExchangeRates::<USD>::new();
rates.set(EUR::CODE, dec!(0.8));
rates.set(IDR::CODE, 17_000);
let ret = money.convert::<EUR>(&rates);
assert_eq!(ret.unwrap().amount(), dec!(98.4));
let ret = money.convert::<IDR>(&rates);
assert_eq!(ret.unwrap().amount(), dec!(2_091_000));
let money = Money::<EUR>::new(123).unwrap();
let ret = money.convert::<IDR>(rates);
assert_eq!(ret.unwrap().amount(), dec!(2_613_750));
let rates = ExchangeRates::<USD>::from([
("EUR", dec!(0.8)),
("IDR", dec!(17_000)),
("IRR", dec!(1_321_700)),
("USD", dec!(123)), // will be ignored since base already in usd and forced into 1.
]);
let money = Money::<USD>::from_decimal(dec!(1000));
assert_eq!(money.convert::<USD>(&rates).unwrap().amount(), dec!(1000));
assert_eq!(money.convert::<EUR>(&rates).unwrap().amount(), dec!(800));
assert_eq!(
money.convert::<IRR>(&rates).unwrap().amount(),
dec!(1_321_700_000)
);
assert_eq!(
money.convert::<IDR>(&rates).unwrap().amount(),
dec!(17_000_000)
);
let money = Money::<EUR>::new(12).unwrap();
assert_eq!(
money.convert::<IDR>(&rates).unwrap().amount(),
dec!(255_000)
);
let money = Money::<EUR>::new(1230).unwrap();
assert_eq!(
money.convert::<USD>(&rates).unwrap().amount(),
dec!(1_537.5)
);
let money = Money::<IDR>::new(15_000_000).unwrap();
assert_eq!(
money.convert::<IRR>(&rates).unwrap().amount(),
dec!(1_166_205_882.35)
);
let money = Money::<IRR>::new(5000).unwrap();
assert_eq!(money.convert::<USD>(&rates).unwrap().amount(), dec!(0));
let money = Money::<IRR>::new(10000).unwrap();
assert_eq!(money.convert::<EUR>(&rates).unwrap().amount(), dec!(0.01));
// CAD is not in the rates, so None returned.
assert!(money.convert::<CAD>(rates).is_none());Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.