# Crate oxydized_money

source Â·## Expand description

## Â§Oxydized Money ðŸ’µ â†” ðŸ’¶

This crate aims at providing data types to manipulate amounts of money in specific currencies, convert amounts between currencies and make sure that any computation is performed on amounts of the same currency.

### Â§Motivations

This crate was introduced because all the existing known alternatives have some signigicant drawbacks:

- using native floating point type like
`f32`

or`f64`

suffer from their lack of precision. - using
`rust_decimal::Decimal`

solves this issue but does not prevent from adding amounts in different currency. - using
`rusty_money::Money`

, although slightly better, does not really solve the conversion issue because performing arithmetic operations on amounts of different currencies panics.

Rust being dedicated to proper error handling, all these options feel like compromises. This crate aims to improve this by by providing three distinct data types:

`Amount`

for storing amounts in a given currency.`CurrencyError`

for representing any errors (currency mismatch, â€¦) during arithmetic operations on`Amount`

s.`AmountResult`

for storing the result of arithmetic operations (either an`Amount`

or`CurrencyError`

).

Arithmetic operations are defined in such a way that these three types
inte-roperate almost seemlessly. However, when performing an operation,
the type of output always reflect whether an error could have occured.
Operation that cannot fail will output `Amount`

s and operations that
can fail will outout `AmountResult`

s. Before getting at the underlying
`Amount`

, `AmountResult`

s need to be properly checked for errors.

No more ðŸ¦¶-guns

### Â§Examples

```
use oxydized_money_macros::{eur, usd, dec};
use oxydized_money::{
Currency::{EUR,USD},
CurrencyError,
Decimal,
};
// Amount(USD)
let capital = usd!(10_000);
// Decinal
let exchange_rate = dec!(0.928);
// Amount(EUR)
let converted = capital.converted_to(EUR, exchange_rate);
// Amount(EUR)
let fees = eur!(15.2);
// Amount(EUR) + Amount(EUR) => AmountResult(EUR)
let subtotal = converted + fees;
// Amount(EUR) * Decimal => Amount(EUR)
let extras = eur!(50) * dec!(2);
// AmountResult(EUR) + Amount(EUR) => AmountResult(EUR)
let total = subtotal + extras;
// Comparing AmountResult with Amounts
assert_eq!(total, eur!(9_395.200));
// AmountResult(EUR) + Amount(USD) => AmountResult(Mismatch(EUR,USD))
let oops = total + usd!(20);
// Comparing AmountResult with CurrencyError
assert_eq!(oops, CurrencyError::Mismatch(EUR,USD));
// AmountResult(Mismatch(EUR,USD)) + Amount(USD) => AmountResult(Mismatch(EUR,USD))
let oh_my = oops + usd!(200);
assert_eq!(oh_my, CurrencyError::Mismatch(EUR,USD));
// "Everything, everywhere, all at once."
assert_eq!(
usd!(10_000).converted_to(EUR, dec!(0.928)) + eur!(15.2) + eur!(50)*dec!(2),
eur!(9_395.200)
);
```

### Â§Supported Operations

#### Â§Binary Operations

##### Â§`Amount`

Left Operand | Operator | Right Operand | Output |
---|---|---|---|

`Amount` | `*` | `Decimal` | `Amount` |

`Amount` | `/` | `Decimal` | `AmountResult` |

`Amount` | {`+` ,`-` } | `Amount` | `AmountResult` |

`Amount` | {`+` ,`-` } | `AmountResult` | `AmountResult` |

`Amount` | {`==` ,`!=` } | `Amount` | `bool` |

`Amount` | {`==` ,`!=` } | `AmountResult` | `bool` |

`Amount` | {`<` ,`>` ,`>=` ,`<=` } | `Amount` | `bool` |

##### Â§`AmountResult`

Left Operand | Operator | Right Operand | Output |
---|---|---|---|

`AmountResult` | `*` | `Decimal` | `AmountResult` |

`AmountResult` | `/` | `Decimal` | `AmountResult` |

`AmountResult` | {`+` ,`-` } | `Amount` | `AmountResult` |

`AmountResult` | {`+` ,`-` } | `AmountResult` | `AmountResult` |

`AmountResult` | {`==` ,`!=` } | `Amount` | `bool` |

`AmountResult` | {`==` ,`!=` } | `AmountResult` | `bool` |

`AmountResult` | {`==` ,`!=` } | `CurrencyError` | `bool` |

##### Â§`CurrencyError`

Left Operand | Operator | Right Operand | Output |
---|---|---|---|

`CurrencyError` | {`==` ,`!=` } | `AmountResult` | `bool` |

`CurrencyError` | {`==` ,`!=` } | `CurrencyError` | `bool` |

#### Â§Unary Operations

##### Â§`Amount`

Operator | Operand | Output |
---|---|---|

`-` | `Amount` | `Amount` |

##### Â§`AmountResult`

Operator | Operand | Output |
---|---|---|

`-` | `AmountResult` | `AmountResult` |

## StructsÂ§

`AmountResult`

represents the result of a computation involving amounts of money. It can therefore either be an`Amount`

if the computation was successful, or a`CurrencyError`

if the computation was not successful.`Decimal`

represents a 128 bit representation of a fixed-precision decimal number. The finite set of values of type`Decimal`

are of the form m / 10^{e}, where m is an integer such that -2^{96}< m < 2^{96}, and e is an integer between 0 and 28 inclusive.

## EnumsÂ§

`CurrencyError`

represents all currency error that can occur during arithmetic operations with`Amount`

or`AmounrResult`

.

## Type AliasesÂ§

- Type alias for a
`Result`

where the error is`CurrencyError`