lucre
An ergonomic Rust library for handling money.
Represent money without generics or lifetimes, and without giving up safety or speed. ISO 4217 currency definitions are built in.
Install
Add lucre to your Cargo.toml.
[]
= "0.11.0"
Usage
Money is the main type. Currency supports it, and holds a constant for
every current ISO 4217 currency.
use ;
Several currencies at once
Money will not mix currencies: + panics and comparisons return None. To
carry amounts in more than one currency, use a MoneyBag, which holds a
separate balance for each.
use ;
let mut wallet = new;
wallet += from_major;
wallet += from_major;
assert_eq!;
// A currency the bag has never held has a balance of zero
assert_eq!;
// The same iterator sums either way. The type you ask for decides:
// `Option<Money>` requires one currency, a bag allows several.
let refunds = ;
assert_eq!;
assert_eq!;
// If the currencies differ, only the bag sums
let mixed = ;
assert_eq!;
Converting between currencies
Exchange rates change constantly, so lucre ships none of its own. Supply a rate
you already have and lucre does the arithmetic. An Exchange holds a set of
rates and converts amounts with them.
use Error;
use ;
use dec;
Each rate applies in one direction. A rate for USD against EUR says nothing
about EUR against USD. Iterating a MoneyBag yields each currency's balance in
ISO alphabetic order, so you can convert a whole bag one balance at a time.
A Pair is the two currencies without a rate.
use Error;
use ;
Features
serde
Off by default. Turning it on gives Money, MoneyBag, ExchangeRate,
Exchange, Pair, Currency, IsoAlphabeticCode, IsoNumericCode, and
RoundingMode a Serialize and a Deserialize impl.
[]
= { = "0.11.0", = ["serde"] }
Amounts and rates are written as text. Text keeps the fraction exact and keeps the scale the figure was built with. Numbers are read too, floats included, but only text survives a round trip unchanged.
A bag is one balance per currency, keyed by ISO alphabetic code. Reading adds up whatever the document says, rather than requiring it to match what a bag would have written. A balance of zero leaves no currency behind, and a currency named twice is summed.
A rate states its pair and the multiplier between them. The base is the
currency being priced and the quote is the currency it is priced in. A rate of
zero or less is rejected, as in ExchangeRate::new.
An Exchange is one rate per pair, keyed as BASE/QUOTE. Each direction is
its own entry, and a pair named twice keeps the rate given last.
The smaller types are single values rather than objects:
| Type | Shape | Accepts |
|---|---|---|
Currency |
"USD" |
the three-letter code, unassigned codes rejected |
Pair |
"USD/EUR" |
two codes split by a slash |
IsoAlphabeticCode |
"ZZZ" |
three capitals, assigned or not |
IsoNumericCode |
840 |
an integer of at most three digits |
RoundingMode |
"half-up" |
or "half-down", or "half-even" |
Self-describing formats such as JSON, TOML, and YAML work. Formats without type information, such as bincode and postcard, do not.
Maintainer
This project is maintained by Rosa Richter. For ways to contact her, see her contact page.
Contributing
Questions and contributions are welcome. Please create an issue for bugs, feature requests, or questions.
License
BSD-2-Clause-Patent © Rosa Richter