mod add;
mod add_assign;
#[cfg(feature = "num-traits")]
mod checked_add;
#[cfg(feature = "num-traits")]
mod checked_div;
#[cfg(feature = "num-traits")]
mod checked_mul;
#[cfg(feature = "num-traits")]
mod checked_rem;
#[cfg(feature = "num-traits")]
mod checked_sub;
mod display;
mod div;
mod div_assign;
mod exchange;
mod from_str;
mod mul;
mod mul_assign;
mod rem;
mod rem_assign;
mod sub;
mod sub_assign;
mod try_from;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::{Currency, Decimal};
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Money
{
pub amount: Decimal,
pub currency: Currency,
}
impl Money
{
fn checked(
self,
operation: fn(Decimal, Decimal) -> Option<Decimal>,
operand: Self,
) -> Option<Self>
{
match self.currency == operand.currency
{
false => None,
_ => operation(self.amount, operand.amount)
.map(|amount| Self { amount, currency: self.currency }),
}
}
pub fn checked_add(self, rhs: Self) -> Option<Self>
{
self.checked(Decimal::checked_add, rhs)
}
pub fn checked_div(self, rhs: Self) -> Option<Self>
{
self.checked(Decimal::checked_div, rhs)
}
pub fn checked_mul(self, rhs: Self) -> Option<Self>
{
self.checked(Decimal::checked_mul, rhs)
}
pub fn checked_rem(self, rhs: Self) -> Option<Self>
{
self.checked(Decimal::checked_rem, rhs)
}
pub fn checked_sub(self, rhs: Self) -> Option<Self>
{
self.checked(Decimal::checked_sub, rhs)
}
pub fn new(amount: i64, decimal_places: u32, currency: Currency) -> Self
{
Self { amount: Decimal::new(amount, decimal_places), currency }
}
fn unchecked(self, operation: fn(Decimal, Decimal) -> Decimal, operand: Self) -> Self
{
match self.currency == operand.currency
{
false => panic!(
"Attempted to perform operation on {} and {}, which have differing currencies",
self, operand
),
_ => Self { amount: operation(self.amount, operand.amount), currency: self.currency },
}
}
}