Skip to main content

Exchange

Trait Exchange 

Source
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§

Source

type Target<T: Currency> where Self: Convert<T>

Target conversion.

Required Methods§

Source

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 currency
    • RawMoney<T> where T is target currency
    • Decimal
    • f64
    • i32
    • i64
    • i128
    • ExchangeRates<'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.

Implementors§

Source§

impl<M, C> Exchange<C> for M
where M: BaseMoney<C> + BaseOps<C> + Convert<C>, C: Currency,

Source§

type Target<T: Currency> = <M as Convert<T>>::Output where M: Convert<T>