#currency #precision #money #decimal #utilities #floating-point #integer

currency_rs_isotoxal

这是一个用于处理货币的 Rust 库,它使用更少的生命周期和更多的堆内存,如果你需要,可以使用 currency_rs。

1 个稳定版本

1.1.3 2023 年 4 月 15 日

#120金融


用于 fig_cli

自定义许可证

56KB
1.5K SLoC

currency_rs logo

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"

许可证

MIT

依赖项

~3–4.5MB
~75K SLoC