2 releases
| 0.1.1 | Nov 8, 2019 |
|---|---|
| 0.1.0 | Oct 31, 2019 |
#7 in #exponent
30KB
565 lines
Monet
Handle currency conversion and common operations (addition, subtraction, multiplication, division).
How it works
It defines some base types:
CurrencyAmountisi128and, as the name says, is used to store amounts.CurrencyCodeis a wrapper for[u8; 3]that can be created from / converted into&strs.Moneyis the most important type. Money holds both acurrency_codeand anamount. It's used to store money and to perform operations. It can be converted into another currency code by providingRates.Ratesis a wrapper for aHashMap. It can be constructed from such pre-defined map orpopulated from an external source such as websites(Not yet, TODO: Implement).Exponentexists because there are nofloats involved here. It has two fields:amountandexponent. Its decimal value isamount / (10).pow(exponent).
Dangers
Even this library isn't safe from precision losses. For example, an Exponent's amount could be cut out by its exponent. Also errors when converting money could occurr.
Examples
Summing two Moneys of the same type
use monet::{Money, CurrencyAmount, Rates, Operation};
use std::convert::TryInto;
// Custom rates.
let map = vec![("USD", 1_000_000)].into_iter()
.map(|(code, worth)| (code.try_into().unwrap(), worth.into())
.collect();
let rates = Rates::with_rates(map);
let money_owned = Money::with_str_code(CurrencyAmount::with_unit(2), "USD").unwrap();
let money_paid = Money::with_str_code(CurrencyAmount::with_unit(1), "USD").unwrap();
let remaining = (money_owned - money_paid).execute(&rates);
assert_eq!(remaining, Money::with_str_code(CurrencyAmount::with_unit(1), "USD"));
assert_eq!(remaining, Money::with_str_code(1_000_000.into(), "USD"));
Summing two Moneys of different type
use monet::{Money, CurrencyAmount, Rates, Operation};
use std::convert::TryInto;
// Custom rates.
let map = vec![
("USD", 1_000_000),
("CHF", 1_100_000),
].into_iter()
.map(|(code, worth)| (code.try_into().unwrap(), worth.into())
.collect();
let rates = Rates::with_rates(map);
let money_one = Money::with_str_code(1_000_000.into(), "CHF").unwrap();
let money_two = Money::with_str_code(1_100_000.into(), "USD").unwrap();
// Note: sum has currency code "CHF": when summing,
// the currency code of the first money is used
let sum = (money_one + money_two).execute(&rates);
assert_eq!(remaining, Money::with_str_code(2_000_000.into(), "CHF"));
Chaining operations
use monet::{Money, CurrencyAmount, Rates, Operation};
use std::convert::TryInto;
// Custom rates.
let map = vec![
("USD", 1_000_000),
("CHF", 1_100_000),
].into_iter()
.map(|(code, worth)| (code.try_into().unwrap(), worth.into())
.collect();
let rates = Rates::with_rates(map);
let money_one = Money::with_str_code(1_000_000.into(), "CHF").unwrap();
let money_two = Money::with_str_code(1_100_000.into(), "USD").unwrap();
let money_three = Money::with_str_code(2_000_000.into(), "CHF").unwrap();
// Note: sum has currency code "CHF"
let sum = (money_one + money_two - money_three).execute(&rates);
assert_eq!(remaining, Money::with_str_code(0.into(), "CHF"));
Dependencies
~195KB