#货币 #金钱 #xand #tpfs #数学

xand_money

一个实用程序crate,用于安全解析和转换Xand和法定货币值

1个稳定版本

2.0.4 2023年2月14日

#1621解析器实现

MIT 许可证

30KB
507

目录

关于

xand_money 子模块提供了在 xand_banks 和其他crate中安全处理货币值的方法。

它公开了如 Usd 这样的法定货币类型用于货币,以及一个 Xand 类型来表示数字索赔。该类可扩展到其他法定货币。

Xand 类型表示Xand网络上的值,不能为负。

法定货币类型 Usd 表示与银行通信的货币值,可以是负数。

这个crate旨在防止所有数值数据丢失(与IEE-754编码的浮点值一起工作的舍入和精度错误),这在处理金钱时尤为重要。

入门指南

这个crate可以从TPFS内部crate注册表中获取。

Cargo.toml 中将 xand_money 添加到您的项目中,

xand_money= {版本= "<期望版本>",注册表= "tpfs" }

金钱类型

Usd

Usd 的内部类型是(目前)一个 Decimal,可以以主要单位(1.23)或次要单位(123)返回。注意:Usd 的内部类型是一个私有实现细节,不应依赖于它。

转换

转换为Usd

Usd 类型允许将 f64i64u64 和从第三方银行API接收到的 &str 类型转换为 xand-banks 和其他crate中的USD货币表示。

例如,从浮点数转换

let foo: f64 = 1.23;
let usd = Usd::from_f64(foo)?;

从Usd转换

Usd 类型允许转换为 f64

let usd = Usd::from_f64(15_149.99_f64)?;
let num: f64 = f64::try_from(usd)?;

Usd 类型还允许 u64i64 的次要单位表示,尽管由于这些类型的边界不同,表示可能失败,在这种情况下将返回错误

let usd = Usd::from_f64(15_149.99_f64)?;
let i_minor_units: i64 = usd.into_i64_minor_units()?;
let u_minor_units: u64 = usd.into_u64_minor_units()?;

Usd转换为Decimal

Usd 可以使用其实例方法之一转换为 Decimal,从而支持该类型支持的转换,请参阅文档

相等比较

xand_money 中的类型实现了类似类型的完全和部分相等。

为了比较不同的货币值,需要将它们转换为相同的货币类型。

let usd1 = Usd::from_f64(123.00)?;
let usd2 = Usd::from_i64(123);
assert_eq!(usd1, usd2);

算术运算

为了使用不同货币值表示形式(例如 Usdf64)进行算术计算,它们必须首先通过使用类型的 as_major_units()as_minor_units() 实例方法将它们转换为 Decimal 格式。

例如

let usd1 = Usd::from_f64(1.23)?;
let usd2 = Usd::from_f64(1.23)?;
let usd3 = Usd::from_i64(1);
assert_ne!(usd1.as_major_units(), usd2.as_major_units() + usd3.as_major_units());

注意:Xand 父类只能添加到自身,不能转换为其他类型。

错误处理

xand_money 类产生的错误可以在银行实现中的更具体的错误枚举中被消费

foo
.bar()
.map_or_else(
        |e: MoneyError| Err(BazBankAdapterError {
            source: Arc::new(MoneyError::ErrorConstructingDecimal),
            message: "Failed to parse transaction amount from string".to_string()
            }),
        |val| Ok(val))

然而,在不可靠的操作(例如构建请求数据)中,错误不会被访问,因为失败情况将导致崩溃

...
let amt: Usd  = xfer.amount;

XferReq {
    xfer_req: Some(XferReqXferReq {
        ...
        xfer_info: Some(XferInfo {
            ...
            cur_amt: Some(CurAmt {
                amt: match amt.as_major_units().to_f32(){
                    Some(amt) => Some(amt),
                    None => panic!(), // XferReq does not allow this conversion to fail
                }
            })
        }),
    }),

依赖

~1–1.6MB
~34K SLoC