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:
CurrencyAmount
isi128
and, as the name says, is used to store amounts.CurrencyCode
is a wrapper for[u8; 3]
that can be created from / converted into&str
s.Money
is the most important type. Money holds both acurrency_code
and anamount
. It's used to store money and to perform operations. It can be converted into another currency code by providingRates
.Rates
is 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).Exponent
exists because there are nofloat
s involved here. It has two fields:amount
andexponent
. 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 Money
s 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 Money
s 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