Crates.io | currencies |
lib.rs | currencies |
version | 0.4.1 |
source | src |
created_at | 2023-08-13 07:10:20.118495 |
updated_at | 2024-06-21 06:36:36.364493 |
description | Allows for generic manipulation of currencies (both real-world and cryptocurrencies) with optionally compile-time enforced checked math and support for all ISO-4217 currencies. |
homepage | |
repository | https://github.com/sam0x17/currencies |
max_upload_size | |
id | 943173 |
size | 11,623 |
This crate provides a generic Currency
and corresponding Amount
type that can handle basic
arithmetic operations and formatting of arbitrary currencies and cryptocurrencies. Main
features include:
ETH
, BTC
, DOT
, and a variety of other
cryptocurrencies are included.Amount
is forced to only make use of unchecked math, or
not, at compile-time. Normally this is impossible to control since the core:ops
operators
are set up such that the checked operators require their unchecked counterparts to be
implemented on the host type, however I have gone out of my way to make it possible to
implement unchecked math only, and control it easily with a Amount<ETH, Checked>
-style
switch. This is extremely desirable for scenarios where panicking could cause a catastrophic
issue, and the way it is set up, programmers are forced to consume the Option
returned by
the checked ops.define_currency!
that can define new currencies on-the-fly.primitive_types::U256
that implements many more useful
num-traits
and num-integer
traits than what Parity includes with the num-traits
feature, and are often required when working with amounts of a currency.num-traits
and num-integer
traits.#[test]
fn show_off_currency_math() {
use currency::*;
let apple_cost = amt!(USD, "$3.24");
let orange_cost = Amount::<USD>::from_raw(7_97);
assert!(apple_cost < orange_cost);
assert!(apple_cost + orange_cost > orange_cost);
assert_eq!(format!("{}", apple_cost * orange_cost), "$25.82");
assert_eq!(format!("{}", apple_cost * 3), "$9.72");
let mut total = amt!(DOT, "57622449841.0000000004 DOT");
total -= amt!(DOT, "1000.0 DOT");
total *= Amount::from_raw(2_0000000000u64.into());
assert_eq!(format!("{}", total), "115244897682.0000000008 DOT");
}
#[test]
fn show_off_checked_math() {
use currency::*;
use safety::*;
// When using currency amounts with `Safety = Checked`, the Amount struct has been specially set
// up so that only checked math will be allowed, and you can still use the normal
// operator-based syntax. Thus currency amounts like this should never panic and are
// suitable for use in critical/infallible environments.
let drink_cost = amt_checked!(USD, "$6.29");
let movie_cost = Amount::<USD, Checked>::from_raw(24_99);
let Some(outing_cost) = drink_cost + movie_cost else {
unimplemented!("compiler forces you to handle this!")
};
assert_eq!(format!("{}", outing_cost), "$31.28");
}
Amount
via a decimal literalSignedness
support to Amount
Positive