#money #currency #serde

paft-money

Currency and money primitives for the paft ecosystem

10 releases (4 breaking)

Uses new Rust 2024

0.7.1 Oct 31, 2025
0.7.0 Oct 28, 2025
0.6.0 Oct 21, 2025
0.5.2 Oct 19, 2025
0.3.2 Oct 3, 2025

#289 in Finance

Download history 465/week @ 2025-10-18 217/week @ 2025-10-25 56/week @ 2025-11-01 27/week @ 2025-11-08 44/week @ 2025-11-15 32/week @ 2025-11-22 43/week @ 2025-11-29 31/week @ 2025-12-06 50/week @ 2025-12-13 137/week @ 2025-12-20 93/week @ 2025-12-27 75/week @ 2026-01-03 70/week @ 2026-01-10 73/week @ 2026-01-17 79/week @ 2026-01-24 232/week @ 2026-01-31

460 downloads per month
Used in 12 crates (5 directly)

MIT license

93KB
1.5K SLoC

paft-money

Currency and money primitives for the paft ecosystem.

Crates.io Docs.rs

  • Currency with ISO 4217 integration and extensible fallback
  • Money with safe arithmetic and explicit conversions via ExchangeRate
  • Backend-agnostic decimals (default rust_decimal, optional bigdecimal feature)
  • Runtime currency metadata overlays for non-ISO minor units (e.g., XAU, XDR)

Install

Prefer the facade crate for most applications:

[dependencies]
paft = "0.7.1"

Advanced (direct dependency, default backend):

[dependencies]
paft-money = "0.7.1"

Alternate decimal backend:

[dependencies]
paft-money = { version = "0.7.1", features = ["bigdecimal"] }

With DataFrame integration or panicking ops:

[dependencies]
paft-money = { version = "0.7.1", features = ["dataframe", "panicking-money-ops"] }

Features

  • bigdecimal: switch to arbitrary precision decimals
  • dataframe: Polars integration (ToDataFrame/ToDataFrameVec)
  • panicking-money-ops: opt-in operator overloading that panics on invalid operations
  • money-formatting: locale-aware formatting and strict parsing for Money

Quickstart

use iso_currency::Currency as IsoCurrency;
use paft_money::{Currency, Money};

let price = Money::from_canonical_str("12.34", Currency::Iso(IsoCurrency::USD))?;
let tax   = Money::from_canonical_str("1.23",  Currency::Iso(IsoCurrency::USD))?;
let total = price.try_add(&tax)?;
assert_eq!(total.format(), "13.57 USD");
# Ok::<(), paft_money::MoneyError>(())

Locale-aware formatting

When you enable the optional money-formatting feature, localized output lives behind explicit APIs so the canonical Display remains stable ("<amount> <CODE>").

# #[cfg(feature = "money-formatting")]
# {
use iso_currency::Currency as IsoCurrency;
use paft_money::{Currency, Locale, Money};

let eur = Money::from_canonical_str("1234.56", Currency::Iso(IsoCurrency::EUR)).unwrap();
assert_eq!(format!("{eur}"), "1234.56 EUR");
assert_eq!(eur.format_with_locale(Locale::EnEu).unwrap(), "€1.234,56");
assert_eq!(format!("{}", eur.localized(Locale::EnEu).with_code()), "€1.234,56 EUR");

let parsed =
    Money::from_str_locale("€1.234,56", Currency::Iso(IsoCurrency::EUR), Locale::EnEu).unwrap();
assert_eq!(parsed.format(), "1234.56 EUR");
# }

Dependencies

~1–23MB
~301K SLoC