Skip to content

Commit

Permalink
Simplify exchange_rate handling
Browse files Browse the repository at this point in the history
  • Loading branch information
sharkdp authored and David Peter committed Oct 8, 2023
1 parent 0c913f7 commit 3e65abf
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 37 deletions.
33 changes: 13 additions & 20 deletions numbat/modules/units/currencies.nbt
Original file line number Diff line number Diff line change
@@ -1,37 +1,30 @@
use core::scalar
use units::currency

# This module is currently not part of the prelude, because the 'exchange_rate_XXX' calls
# are blocking. In the CLI application, we do however load this module asynchronously after
# prefetching the exchange rates.

# TODO: once we support strings as function parameters, use 'exchange_rate("USD")' and
# similar instead of separate functions.
fn exchange_rate_USD() -> Scalar
fn exchange_rate_JPY() -> Scalar
fn exchange_rate_GBP() -> Scalar
fn exchange_rate_CNY() -> Scalar
fn exchange_rate_AUD() -> Scalar
fn exchange_rate_CAD() -> Scalar
fn exchange_rate_CHF() -> Scalar
# This module is currently not part of the prelude, because the 'exchange_rate("XYZ")' calls
# are blocking. For the CLI application, we do however load this module on demand if one of
# the identifiers below is. For the Web version, we asynchronously load exchange rates and then
# pull in this module.

fn exchange_rate(currency: str) -> Scalar

@aliases(dollars, USD, $: short)
unit dollar: Money = EUR / exchange_rate_USD()
unit dollar: Money = EUR / exchange_rate("USD")

@aliases(yens, JPY, ¥: short, 円)
unit yen: Money = EUR / exchange_rate_JPY()
unit yen: Money = EUR / exchange_rate("JPY")

@aliases(pound_sterling, GBP, £: short)
unit british_pound: Money = EUR / exchange_rate_GBP()
unit british_pound: Money = EUR / exchange_rate("GBP")

@aliases(CNY: short, 元)
unit renminbi: Money = EUR / exchange_rate_CNY()
unit renminbi: Money = EUR / exchange_rate("CNY")

@aliases(australian_dollars, AUD: short, A$)
unit australian_dollar: Money = EUR / exchange_rate_AUD()
unit australian_dollar: Money = EUR / exchange_rate("AUD")

@aliases(canadian_dollars, CAD: short, C$)
unit canadian_dollar: Money = EUR / exchange_rate_CAD()
unit canadian_dollar: Money = EUR / exchange_rate("CAD")

@aliases(swiss_francs, CHF: short)
unit swiss_franc: Money = EUR / exchange_rate_CHF()
unit swiss_franc: Money = EUR / exchange_rate("CHF")
2 changes: 2 additions & 0 deletions numbat/modules/units/currency.nbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ dimension Money

@aliases(euros, EUR, €: short)
unit euro: Money

# See currencies.nbt for non-Euro currencies
35 changes: 18 additions & 17 deletions numbat/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,16 +298,14 @@ pub(crate) fn functions() -> &'static HashMap<String, ForeignFunction> {
},
);

for currency in ["USD", "JPY", "GBP", "CNY", "AUD", "CAD", "CHF"] {
m.insert(
format!("exchange_rate_{currency}"),
ForeignFunction {
name: format!("exchange_rate_{currency}"),
arity: 0..=0,
callable: Callable::Function(exchange_rate(currency)),
},
);
}
m.insert(
format!("exchange_rate"),
ForeignFunction {
name: "exchange_rate".into(),
arity: 1..=1,
callable: Callable::Function(Box::new(exchange_rate)),
},
);

m.insert(
"str_length".to_string(),
Expand Down Expand Up @@ -694,13 +692,16 @@ fn minimum(args: &[Value]) -> Result<Value> {
)))
}

fn exchange_rate(rate: &'static str) -> BoxedFunction {
Box::new(|_args: &[Value]| -> Result<Value> {
let exchange_rates = ExchangeRatesCache::new();
Ok(Value::Quantity(Quantity::from_scalar(
exchange_rates.get_rate(rate).unwrap_or(f64::NAN),
)))
})
fn exchange_rate(args: &[Value]) -> Result<Value> {
assert!(args.len() == 1);

let rate = args[0].unsafe_as_string();

let exchange_rates = ExchangeRatesCache::new();

Ok(Value::Quantity(Quantity::from_scalar(
exchange_rates.get_rate(rate).unwrap_or(f64::NAN),
)))
}

fn str_length(args: &[Value]) -> Result<Value> {
Expand Down

0 comments on commit 3e65abf

Please sign in to comment.