3 个版本 (重大更新)
0.3.0 | 2024 年 3 月 10 日 |
---|---|
0.2.0 | 2024 年 3 月 3 日 |
0.1.0 | 2024 年 3 月 3 日 |
在 金融 中排名 #228
每月下载量 107
43KB
844 行
氧化货币 💵 ↔ 💶
本软件包旨在提供用于操作特定货币的金额、在不同货币之间转换金额并确保任何计算都在同一货币的金额上执行的数据类型。
动机
引入此软件包是因为所有现有的已知替代品都有一些显著的缺点
- 使用原生的浮点类型如
f32
或f64
由于其缺乏精度而存在问题。 - 使用
rust_decimal::Decimal
解决了这个问题,但无法防止在不同货币中添加金额。 - 使用
rusty_money::Money
,虽然稍微好一些,但并没有真正解决转换问题,因为对不同货币的金额执行算术运算会导致恐慌。
Rust 致力于正确的错误处理,所有这些选项都感觉像是一种妥协。本软件包旨在通过提供三种不同的数据类型来改进这一点
Amount
用于存储给定货币的金额。CurrencyError
用于表示在Amount
上执行算术操作期间出现的任何错误(货币不匹配等)。AmountResult
用于存储算术运算的结果(一个Amount
或CurrencyError
)。
算术运算被定义为这三种类型几乎无缝地交互。然而,在进行运算时,输出类型总是反映了是否可能发生错误。不会失败的运算将输出Amount
,而可能失败的运算将输出AmountResult
。在获取底层Amount
之前,需要适当检查AmountResult
是否存在错误。
不再有🦶-枪
示例
use oxydized_money_macros::{eur, usd, dec};
use oxydized_money::{
Currency::{EUR,USD},
CurrencyError,
Decimal,
};
// Amount(USD)
let capital = usd!(10_000);
// Decinal
let exchange_rate = dec!(0.928);
// Amount(EUR)
let converted = capital.converted_to(EUR, exchange_rate);
// Amount(EUR)
let fees = eur!(15.2);
// Amount(EUR) + Amount(EUR) => AmountResult(EUR)
let subtotal = converted + fees;
// Amount(EUR) * Decimal => Amount(EUR)
let extras = eur!(50) * dec!(2);
// AmountResult(EUR) + Amount(EUR) => AmountResult(EUR)
let total = subtotal + extras;
// Comparing AmountResult with Amounts
assert_eq!(total, eur!(9_395.200));
#
// AmountResult(EUR) + Amount(USD) => AmountResult(Mismatch(EUR,USD))
let oops = total + usd!(20);
// Comparing AmountResult with CurrencyError
assert_eq!(oops, CurrencyError::Mismatch(EUR,USD));
// AmountResult(Mismatch(EUR,USD)) + Amount(USD) => AmountResult(Mismatch(EUR,USD))
let oh_my = oops + usd!(200);
assert_eq!(oh_my, CurrencyError::Mismatch(EUR,USD));
// "Everything, everywhere, all at once."
assert_eq!(
usd!(10_000).converted_to(EUR, dec!(0.928)) + eur!(15.2) + eur!(50)*dec!(2),
eur!(9_395.200)
);
支持的运算
二元运算
Amount
左操作数 | 运算符 | 右操作数 | 输出 |
---|---|---|---|
Amount |
* |
十进制 |
Amount |
Amount |
/ |
十进制 |
AmountResult |
Amount |
{+ ,- } |
Amount |
AmountResult |
Amount |
{+ ,- } |
AmountResult |
AmountResult |
Amount |
{== ,!= } |
Amount |
布尔型 |
Amount |
{== ,!= } |
AmountResult |
布尔型 |
Amount |
{< ,> ,>= ,<= } |
Amount |
布尔型 |
AmountResult
左操作数 | 运算符 | 右操作数 | 输出 |
---|---|---|---|
AmountResult |
* |
十进制 |
AmountResult |
AmountResult |
/ |
十进制 |
AmountResult |
AmountResult |
{+ ,- } |
Amount |
AmountResult |
AmountResult |
{+ ,- } |
AmountResult |
AmountResult |
AmountResult |
{== ,!= } |
Amount |
布尔型 |
AmountResult |
{== ,!= } |
AmountResult |
布尔型 |
AmountResult |
{== ,!= } |
CurrencyError |
布尔型 |
CurrencyError
左操作数 | 运算符 | 右操作数 | 输出 |
---|---|---|---|
CurrencyError |
{== ,!= } |
AmountResult |
布尔型 |
CurrencyError |
{== ,!= } |
CurrencyError |
布尔型 |
一元运算
Amount
运算符 | 操作数 | 输出 |
---|---|---|
- |
Amount |
Amount |
AmountResult
运算符 | 操作数 | 输出 |
---|---|---|
- |
AmountResult |
AmountResult |
依赖项
~0.7–1MB
~22K SLoC