2 个不稳定版本
0.2.0 | 2024 年 3 月 3 日 |
---|---|
0.1.0 | 2024 年 3 月 3 日 |
在 金融 分类中排名 #115
10KB
Oxydized Money 💵 ↔ 💶
该库旨在提供数据类型来操作特定货币的金额、在货币之间转换金额并确保任何计算都在相同货币的金额上执行。
动机
引入此库是因为所有已知的现有替代方案都有一些显著的缺点
- 使用原生浮点类型如
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)
);
支持的操作
二进制运算
数量
左操作数 | 运算符 | 右操作数 | 输出 |
---|---|---|---|
数量 |
* |
十进制 |
数量 |
数量 |
/ |
十进制 |
结果数量 |
数量 |
{+ ,- } |
数量 |
结果数量 |
数量 |
{+ ,- } |
结果数量 |
结果数量 |
数量 |
{== ,!= } |
数量 |
布尔值 |
数量 |
{== ,!= } |
结果数量 |
布尔值 |
数量 |
{< ,> ,>= ,<= } |
数量 |
布尔值 |
结果数量
左操作数 | 运算符 | 右操作数 | 输出 |
---|---|---|---|
结果数量 |
* |
十进制 |
结果数量 |
结果数量 |
/ |
十进制 |
结果数量 |
结果数量 |
{+ ,- } |
数量 |
结果数量 |
结果数量 |
{+ ,- } |
结果数量 |
结果数量 |
结果数量 |
{== ,!= } |
数量 |
布尔值 |
结果数量 |
{== ,!= } |
结果数量 |
布尔值 |
结果数量 |
{== ,!= } |
货币错误 |
布尔值 |
货币错误
左操作数 | 运算符 | 右操作数 | 输出 |
---|---|---|---|
货币错误 |
{== ,!= } |
结果数量 |
布尔值 |
货币错误 |
{== ,!= } |
货币错误 |
布尔值 |
一元运算
数量
运算符 | 操作数 | 输出 |
---|---|---|
- |
数量 |
数量 |
结果数量
运算符 | 操作数 | 输出 |
---|---|---|
- |
结果数量 |
结果数量 |
依赖项
~550–770KB
~15K SLoC