Monies   ![Build Status] ![Latest Version] ![Docs]

Monies handles the messy parts of dealing with money like rounding, precision, parsing and internationalization. It supports ISO-4217 currencies, common crypto currencies and lets you define your own. The main items exported by the library are Money and the iso currency sets.

Usage

A Money object is created by supplying an amount and a currency. Amounts can be specified in numeric or string types but will be stored as precise decimals internally. You can select a bundled currency or make your own. Here's a quick example of how you would make your own Currency and then create some Money with it:

```rust use Monies::{Money, definecurrencyset};

definecurrencyset!( videogame { GIL: { code: "GIL", exponent: 2, locale: Locale::EnUs, minorunits: 100, name: "GIL", symbol: "G", symbol_first: true, } } );

Money::frommajor(2000, videogame::GIL); // 2000 GIL Money::fromminor(200000, videogame::GIL); // 2000 GIL Money::fromstr("2,000.00", videogame::GIL).unwrap(); // 2000 GIL

// Currencies can be looked up by code. let gil = videogame::find("GIL").unwrap();
Money::from
major(2_000, gil); // 2000 GIL ```

The currency sets can then be used like this:

```rust use Monies::{Money, iso};

Money::frommajor(2000, iso::USD); // 2000 U.S Dollars Money::frommajor(2000, iso::GBP); // 2000 British Pounds Money::from_major(2, crypto::BTC); // 2 Bitcoin ```

Money objects of the same currency can be compared:

```rust use Monies::{Money, iso}; let hundred = Money::fromminor(10000, iso::USD); let thousand = Money::fromminor(100000, iso::USD);

println!("{}", thousand > hundred); // false println!("{}", thousand.is_positive()); // true ```

Precision, Rounding and Math

Money objects are immutable, and operations that change amounts create a new instance of Money. Amounts are stored as 128 bit fixed-precision Decimals, and handle values as large as 296 / 1028. Operations on Money retain the maximum possible precision. When you want less precision, you call the round function, which supports three modes:

Money can be added, subtracted, multiplied and divided like this:

```rust use Monies::{Money, Round, iso};

Money::fromminor(100, iso::USD) + Money::fromminor(100, iso::USD); // 2 USD Money::fromminor(100, iso::USD) - Money::fromminor(100, iso::USD); // 0 USD Money::fromminor(100, iso::USD) * 3; // 3 USD Money::fromminor(100, iso::USD) / 3; // 0.333... USD

let usd = Money::from_str("-2000.005", iso::USD).unwrap(); // 2000.005 USD usd.round(2, Round::HalfEven); // 2000.00 USD usd.round(2, Round::HalfUp); // 2000.01 USD usd.round(0, Round::HalfUp); // 2000 USD ```

Formatting

Calling format! or println! on Money returns a string with a rounded amount, using separators and symbols according to the locale of the currency. If you need to customize this output, the Formatter module accepts a more detailed set of parameters.

```rust use Monies::{Money, iso}; let usd = Money::fromstr("-2000.009", iso::USD).unwrap(); let eur = Money::fromstr("-2000.009", iso::EUR).unwrap();

println!("{}", usd); // -$2,000.01 println!("{}", eur); // -€2.000,01; ```

Exchange

The library also provides two additional types - Exchange and ExchangeRates to convert Money from one currency to another.

```rust use Monies::{Money, Exchange, ExchangeRate, iso}; use rustdecimalmacros::*;

// Convert 1000 USD to EUR at a 2:1 exchange rate. let rate = ExchangeRate::new(iso::USD, iso::EUR, dec!(0.5)).unwrap(); rate.convert(Money::fromminor(100000, iso::USD)); // 500 EUR

// An Exchange can be used to store ExchangeRates for later use let mut exchange = Exchange::new(); exchange.setrate(&rate); exchange.getrate(iso::USD, iso::EUR); ```