Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
use super::math_rational::{multiply_rational, rational, rational_from_value, rational_to_integer}; ← from math.rational ^1.0.0 · built alongside by fune
use super::money_amount::{money, money_from_value, money_to_value, Money}; ← from money.amount ^1.0.0 · built alongside by fune
use super::money_currency_digits::currency_digits; ← from money.currency-digits ^1.0.0 · built alongside by fune
/// Convert `amount` into the rate's quote currency.
///
/// Exact up to one final rounding into the quote currency's minor unit; the
/// rate is a fraction in major units and each currency's decimal places are
/// looked up rather than assumed to be two.
///
/// # Panics
/// Panics if the amount is not in the rate's base currency, the rate is not
/// positive, a currency has no ISO 4217 minor unit, or the exact value
/// overflows `math.rational`'s range.
pub fn convert_money(amount: &Money, rate: &ExchangeRate, mode: &str) -> Money {
if amount.currency != rate.base {
panic!(
"exchange rate converts {} to {}, not {}",
rate.base, rate.quote, amount.currency
);
}
let r = rational(rate.rate.numerator, rate.rate.denominator);
if r.numerator <= 0 {
panic!("exchange rate must be positive");
}
let from_digits = currency_digits(&rate.base) as u32;
let to_digits = currency_digits(&rate.quote) as u32;
// minor units of quote per minor unit of base: rate x 10^to_digits / 10^from_digits
let scale = rational(10_i64.pow(to_digits), 10_i64.pow(from_digits));
let per_minor = multiply_rational(&r, &scale);
let exact = multiply_rational(&rational(amount.minor, 1), &per_minor);
money(rational_to_integer(&exact, mode), &rate.quote)
}
pub fn exchange_rate_from_value(v: &Value) -> ExchangeRate {
ExchangeRate {
base: v.get("base").as_str().to_string(),
quote: v.get("quote").as_str().to_string(),
rate: rational_from_value(v.get("rate")),
}
}
pub fn fune_vector(args: &[Value]) -> Value {
money_to_value(&convert_money(
&money_from_value(&args[0]),
&exchange_rate_from_value(&args[1]),
args[2].as_str(),
))
}