// Monies handles the messy parts of dealing with money like rounding, precision, parsing and internationalization.
// It supports [ISO-4217](https://en.wikipedia.org/wiki/ISO_4217) currencies, common crypto currencies and lets you
// define your own. The main items exported by the library are `Money` and the `iso` and `crypto` currency sets.
//
// The main items exported by the library are `Money` and the `iso` and `crypto` 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:
//
// ```edition2018
// use Monies::{Money, define_currency_set};
//
// define_currency_set!(
//   video_game {
//     GIL: {
//       code: "GIL",
//       exponent: 2,
//       locale: Locale::EnUs,
//       minor_units: 100,
//       name: "GIL",
//       symbol: "G",
//       symbol_first: true,
//     }
//   }
// );
//
// Money::from_major(2_000, video_game::GIL);              // 2000 GIL
// Money::from_minor(200_000, video_game::GIL);            // 2000 GIL
// Money::from_str("2,000.00", video_game::GIL).unwrap();  // 2000 GIL
//  
// // Currencies can be looked up by code.
// let gil = video_game::find("GIL").unwrap();                        
// Money::from_major(2_000, gil);                          // 2000 GIL
// ```
//
// ## Features: Currency Sets
//
// Monies provides two currency sets for convenience : `iso`, which implements ISO-4217 currencies and `crypto` which
// implements popular cryptocurencies. `iso` is enabled by default, and you can add `crypto` by enabling the feature:
//
// ```toml
// [dependencies]
// Monies = { version = "0.4.0", features = ["iso", "crypto"] }
// ```
// The currency sets can then be used like this:
//
// ```edition2018
// use Monies::{Money, iso};
//   
// Money::from_major(2_000, iso::USD);        // 2000 U.S Dollars
// Money::from_major(2_000, iso::GBP);        // 2000 British Pounds
// ```
//
// Money objects of the same currency can be compared:
//
//  ```edition2018
// use Monies::{Money, iso};
//
// let hundred = Money::from_minor(10_000, iso::USD);
// let thousand = Money::from_minor(100_000, 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](https://github.com/paupino/rust-decimal), and handle values as large as
// 2<sup>96</sup> / 10<sup>28</sup>. Operations on Money retain the maximum possible precision. When you want less
// precision, you call the `round` function, which  supports three modes:
//
// * [Half Up](https://en.wikipedia.org/wiki/Rounding#Round_half_up)
// * [Half Down](https://en.wikipedia.org/wiki/Rounding#Round_half_down)
// * [Half Even](https://en.wikipedia.org/wiki/Rounding#Round_half_even) (default)
//
// Money can be added, subtracted, multiplied and divided like this:
//
// ```edition2018
// use Monies::{Money, Round, iso};
//
// Money::from_minor(100, iso::USD) + Money::from_minor(100, iso::USD);  // 2 USD
// Money::from_minor(100, iso::USD) - Money::from_minor(100, iso::USD);  // 0 USD
// Money::from_minor(100, iso::USD) * 3;                                 // 3 USD
// Money::from_minor(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.
//
// ```edition2018
// use Monies::{Money, iso};
//
// let usd = Money::from_str("-2000.009", iso::USD).unwrap();
// let eur = Money::from_str("-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.
//
// ```edition2018
// use Monies::{Money, Exchange, ExchangeRate, iso};
// use rust_decimal_macros::*;
//
// // 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::from_minor(100_000, iso::USD));                    // 500 EUR
//
// // An Exchange can be used to store ExchangeRates for later use
// let mut exchange = Exchange::new();
// exchange.set_rate(&rate);
// exchange.get_rate(iso::USD, iso::EUR);
// ```
//

mod currency;
mod error;
mod exchange;
mod format;
mod locale;
mod money;

pub use currency::*;
pub use error::MoneyError;
pub use exchange::*;
pub use format::*;
pub use locale::*;
pub use money::*;
