1 个稳定版本
1.1.3 | 2023 年 4 月 15 日 |
---|
#120 在 金融
用于 fig_cli
56KB
1.5K SLoC
currency_rs
currency_rs 是一个用于处理货币值的库。它受到 currency.js 的启发,后者是为了解决 JavaScript 中的浮点数问题而构建的。
currency_rs 在幕后以整数形式处理值,解决了许多最基本的精度问题。
2.51 + 0.01; // 2.5199999999999996
Currency::new_float(2.51, None).add(0.01).value(); // 2.52
2.52 - 0.01; // 2.5100000000000002
Currency::new_float(2.52, None).subtract(0.01).value(); // 2.51
这对于大多数 合理的 货币值应该有效。只要你的货币值小于 253(以分计)或 90,071,992,547,409.91,你应该就没有问题。
安装
[dependencies]
currency_rs = "x.y.z"
使用方法
你可以从浮点数、字符串或货币对象本身创建一个货币对象作为值。
Currency::new_float(123., None).to_string(); // 123.00
Currency::new_float(1.23, None).to_string(); // 1.23
Currency::new_string("1.23", None).unwrap().to_string(); // 1.23
Currency::new_string("$12.30", None).unwrap().to_string(); // 12.30
let value = Currency::new_string("123.45", None).unwrap();
Currency::new_cur(value, None).to_string(); // 123.45
货币接受十进制值(例如 1.23
),默认精度为 2,但可以接受较小的货币单位(例如美元中的分)。这将尊重解析时的精度选项。
let opt = CurrencyOpts::new().set_from_cents(true);
Currency::new_float(123., Some(opt.clone())).to_string(); // 1.23
Currency::new_string("123", Some(opt))
.unwrap()
.to_string(); // 1.23
let opt = CurrencyOpts::new()
.set_from_cents(true)
.set_precision(0);
Currency::new_float(123., Some(opt)).to_string(); // 123
let opt = CurrencyOpts::new()
.set_from_cents(true)
.set_precision(3);
Currency::new_float(123., Some(opt)).to_string(); // 1.23
有各种算术方法可以帮助解决浮点数问题的猜测。
Currency::new_float(123.5, None).add(0.23).value(); // 123.73
Currency::new_float(5.0, None).subtract(0.5).value(); // 4.50
Currency::new_float(45.25, None).multiply(3.).value(); // 135.75
Currency::new_float(1.12, None)
.distribute(5)
.iter()
.map(|x| x.value())
.collect::<Vec<f64>>(); // [0.23, 0.23, 0.22, 0.22, 0.22]
甚至还有一个内置的格式化程序,可以自动将逗号分隔符放在正确的位置。
Currency::new_string("2,573,693.75", None)
.unwrap()
.add_string("100,275.50")
.unwrap()
.format(); // "$2,673,969.25"
Currency::new_string("1,237.72", None)
.unwrap()
.subtract(300.)
.format(); // "$937.72"
你还可以更改格式,将十进制和/或分隔符本地化到你的区域设置。
fn euro(value: &str) -> Currency {
let otp = CurrencyOpts::new()
.set_symbol("€")
.set_separator(".")
.set_decimal(",");
Currency::new_string(value, Some(otp)).unwrap()
}
euro("2.573.693,75")
.add_string("100.275,50")
.unwrap()
.format(); // "€2.673.969,25"
euro("1.237,72")
.subtract(300.)
.format(); // "€937,72"
选项
currency_rs 带有一组自己的默认选项,符合 USD。你可以根据你的区域设置进行自定义。
symbol
默认: $
在调用 currency.format()
时包含货币符号。
separator
默认: ,
在调用 currency.format()
时,分隔数字组时使用的分隔符。
decimal
默认: .
在调用 currency.format()
时使用的十进制。
precision
默认: 2
存储为分的小数位数。
pattern
默认: !#
允许您使用!
作为货币符号的替代,并使用#
作为货币金额的替代来自定义格式模式。
negative_pattern
默认: -!#
允许您使用!
作为货币符号的替代,并使用#
作为货币金额的替代来自定义负数格式模式。
error_on_invalid
默认: false
如果传递给Currency::new_string
的值无效,例如abc
,则会抛出错误。
increment
默认: null
在实现需要四舍五入的货币时,设置增量值将允许您设置最接近的增量以将显示值四舍五入到。
let otp = CurrencyOpts::new()
.set_increment(0.05);
Currency::new_float(1.48, Some(otp)).format(); // "$1.50"
use_vedic
默认: false
使用印度数字系统进行数字分组,即10,00,000.00
from_cents
默认: false
将金额值解析为小货币单位(例如美元中的分)而不是美元。
国际化示例
let otp = CurrencyOpts::new()
.set_separator(" ")
.set_decimal(",")
.set_symbol("€");
Currency::new_float(1234.45, Some(otp)).format(); // "€1 234,45"
如果您需要处理多个货币值,最简单的方法是设置具有所需货币设置的工厂函数。
fn usd(value: f64) -> Currency {
let otp = CurrencyOpts::new()
.set_symbol("$")
.set_precision(2);
Currency::new_float(value, Some(otp))
}
fn jpy(value: f64) -> Currency {
let otp = CurrencyOpts::new()
.set_symbol("¥")
.set_precision(0);
Currency::new_float(value, Some(otp))
}
fn gas(value: f64) -> Currency {
let otp = CurrencyOpts::new()
.set_precision(3);
Currency::new_float(value, Some(otp))
}
usd(1234.56).format(); // "$1,234.56"
jpy(1234.56).format(); // "¥1,235"
gas(1234.56).format(); // "$1,234.560"
许可证
依赖项
~3–4.5MB
~75K SLoC