1 unstable release
0.1.0 | Dec 7, 2022 |
---|
#124 in Finance
14KB
198 lines
Katjing
A money library exploring the aplicability of Rusts unique language features for safe money management.
Katjing aims to make money management as safe as possible by checking as much as possible with static typing including rusts borrow checking and life time management.
Feature overview
- Clear ownership Rust tracks ownership
- you can't give the same money instance to multiple parties
- you can't spend money while another instance is borrowing it
- Generic over currency You can't mix money with different currencies
- Cent representation No floating point in money representation, any commas or dots in money representation is for display purposes only, not an attribute of Money
- Separate money and amounts Amounts are not Money
- Separately modelled prices Prices can be paid, consume money and leave change.
Contents
What is this?
Katjing is a Money library meant to be used by applications and libraries that handle monetary transactions and/or calculations.
Why should I use this?
For now if you are feeling adventureous.
Usage
Money can be crated in main parts or cents
use {
katjing::{
Money,
test::SEK
}
};
let one_sek=Money::<SEK>::new(1);
let one_sek_again=Money::<SEK>::in_minor_unit(100);
assert_eq!(one_sek, one_sek_again);
Since money is generic over currencies they can't be mixed (since they are different types)
use {
katjing::{
Money,
test::{SEK, EUR},
}
};
let one_sek=Money::<SEK>::new(1);
let one_eur=Money::<EUR>::new(1);
assert_eq!(one_sek, one_eur); // <-- will not compile
The above example will yeild an error that looks something like this:
error[E0308]: mismatched types
--> src/lib.rs:96:1
|
12 | assert_eq!(one_sek, one_eur);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `SEK`, found struct `EUR`
|
= note: expected struct `Money<SEK>`
found struct `Money<EUR>`
Let's make things more interesting and introduce rust's borrowchecking.
use {
katjing::{
Money,
test::SEK
}
};
fn moving_fn(money:Money<SEK>) {
// do something with owned money
}
let one_sek=Money::<SEK>::new(1);
moving_fn(one_sek);
moving_fn(one_sek); // <-- does not compile
We crate one sek, give it away and then try to give it away again. Rust will complain that you are giving away money that are no longer yours like this:
error[E0382]: use of moved value: `one_sek`
--> src/lib.rs:125:11
|
15 | let one_sek=Money::<SEK>::new(1);
| ------- move occurs because `one_sek` has type `Money<SEK>`, which does not implement the `Copy` trait
16 | moving_fn(one_sek);
| ------- value moved here
17 | moving_fn(one_sek);
| ^^^^^^^ value used here after move
Similarily you cannot lend something you have given away to someone else
use {
katjing::{
Money,
test::SEK
}
};
fn moving_fn(money:Money<SEK>) {
// do something with owned money
}
fn borrowing_fn(money:&Money<SEK>) {
// do something with borrowed money
}
let one_sek=Money::<SEK>::new(1);
moving_fn(one_sek);
borrowing_fn(&one_sek); // <-- does not compile
Yields the following error:
error[E0382]: borrow of moved value: `one_sek`
--> src/lib.rs:162:14
|
19 | let one_sek=Money::<SEK>::new(1);
| ------- move occurs because `one_sek` has type `Money<SEK>`, which does not implement the `Copy` trait
20 | moving_fn(one_sek);
| ------- value moved here
21 | borrowing_fn(&one_sek); // <-- does not compile
| ^^^^^^^^ value borrowed here after move
While this is basic Rust it is pretty unique and I beleive this can be very useful for managing money, also, money can be equally useful for learning about Rust's borrow checker.
Prices
Prices are not money, they state a cost and can be paid for goods to change owners. Katjing models prices as consumers of money.
use {
katjing::{
Money,
Price,
test::SEK
}
};
let ten_sek=Money::<SEK>::new(10);
let nine_sek_price=Price::<SEK>::new(9);
let (change, left_to_pay) = ten_sek.pay(nine_sek_price);
assert_eq!(left_to_pay, Price::<SEK>::new(0));
assert_eq!(change, Money::<SEK>::new(1));
Dependencies
~0.4–0.8MB
~21K SLoC