#money #currency #iso-4217

monies

安全地解析、格式化并进行货币计算

4 个版本

0.0.4 2021年2月9日
0.0.3 2021年1月31日
0.0.2 2021年1月31日
0.0.1 2021年1月30日

#79 in 财务

MIT 许可证

115KB
3K SLoC

Monies − 构建状态 最新版本 文档

Monies 处理处理货币时的繁琐部分,如舍入、精度、解析和国际化。它支持 ISO-4217 货币、常见加密货币,并允许您定义自己的货币。该库导出的主要项是 Moneyiso 货币集。

用法

通过提供一个金额和货币来创建一个 Money 对象。金额可以指定为数字或字符串类型,但将作为精确的小数内部存储。您可以选择捆绑的货币或创建自己的货币。以下是如何创建自己的 Currency 并使用它创建一些 Money 的快速示例

use Monies::{Money, define_currency_set};

define_currency_set!(
  video_game {
    GIL: {
      code: "GIL",
      exponent: 2,
      locale: Locale::EnUs,
      minor_units: 100,
      name: "GIL",
      symbol: "G",
      symbol_first: true,
    }
  }
);

Money::from_major(2_000, video_game::GIL);              // 2000 GIL
Money::from_minor(200_000, video_game::GIL);            // 2000 GIL
Money::from_str("2,000.00", video_game::GIL).unwrap();  // 2000 GIL
 
// Currencies can be looked up by code. 
let gil = video_game::find("GIL").unwrap();                        
Money::from_major(2_000, gil);                          // 2000 GIL

然后可以像这样使用货币集

use Monies::{Money, iso};

Money::from_major(2_000, iso::USD);        // 2000 U.S Dollars
Money::from_major(2_000, iso::GBP);        // 2000 British Pounds
Money::from_major(2, crypto::BTC);         // 2 Bitcoin

货币对象可以像这样进行加、减、乘、除操作

use Monies::{Money, iso};
let hundred = Money::from_minor(10_000, iso::USD);
let thousand = Money::from_minor(100_000, iso::USD);

println!("{}", thousand > hundred);     // false
println!("{}", thousand.is_positive()); // true

精度、舍入和数学

货币对象是不可变的,更改金额的操作会创建一个新的货币实例。金额以 128 位固定精度 Decimals 存储,并处理高达 296 / 1028 的值。货币操作保留最大可能的精度。当您需要更少的精度时,可以调用 round 函数,该函数支持三种模式

货币可以像这样进行加、减、乘、除操作

use Monies::{Money, Round, iso};

Money::from_minor(100, iso::USD) + Money::from_minor(100, iso::USD);  // 2 USD
Money::from_minor(100, iso::USD) - Money::from_minor(100, iso::USD);  // 0 USD
Money::from_minor(100, iso::USD) * 3;                                 // 3 USD
Money::from_minor(100, iso::USD) / 3;                                 // 0.333... USD

let usd = Money::from_str("-2000.005", iso::USD).unwrap();            // 2000.005 USD
usd.round(2, Round::HalfEven);                                        // 2000.00 USD
usd.round(2, Round::HalfUp);                                          // 2000.01 USD
usd.round(0, Round::HalfUp);                                          // 2000 USD

格式化

在货币上调用 format!println! 返回一个字符串,其中包含已舍入的金额,使用货币的本地化分隔符和符号。如果您需要自定义此输出,Formatter 模块接受更详细的参数集。

use Monies::{Money, iso};
let usd = Money::from_str("-2000.009", iso::USD).unwrap();
let eur = Money::from_str("-2000.009", iso::EUR).unwrap();

println!("{}", usd);                                        // -$2,000.01
println!("{}", eur);                                        // -€2.000,01;

交换

该库还提供了两种附加类型 - ExchangeExchangeRates,用于将货币从一种货币转换为另一种货币。

use Monies::{Money, Exchange, ExchangeRate, iso};
use rust_decimal_macros::*;

// Convert 1000 USD to EUR at a 2:1 exchange rate.
let rate = ExchangeRate::new(iso::USD, iso::EUR, dec!(0.5)).unwrap();
rate.convert(Money::from_minor(100_000, iso::USD));                    // 500 EUR

// An Exchange can be used to store ExchangeRates for later use
let mut exchange = Exchange::new();
exchange.set_rate(&rate);
exchange.get_rate(iso::USD, iso::EUR);

依赖关系

~0.9–1.5MB
~33K SLoC