use crate::Money;
#[doc(hidden)]
#[macro_export]
macro_rules! impl_money_ops {
($T:ident) => {
impl<C> ::std::ops::Add for $T<C>
where
C: $crate::Currency,
{
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
let ret = $crate::BaseMoney::amount(&self)
.checked_add($crate::BaseMoney::amount(&rhs))
.expect("addition operation overflow");
<Self as $crate::BaseMoney<C>>::from_decimal(ret)
}
}
impl<C> ::std::ops::Sub for $T<C>
where
C: $crate::Currency,
{
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
let ret = $crate::BaseMoney::amount(&self)
.checked_sub($crate::BaseMoney::amount(&rhs))
.expect("subtraction operation overflow");
<Self as $crate::BaseMoney<C>>::from_decimal(ret)
}
}
impl<C> ::std::ops::AddAssign for $T<C>
where
C: $crate::Currency,
{
fn add_assign(&mut self, other: Self) {
let ret = $crate::BaseMoney::amount(self)
.checked_add($crate::BaseMoney::amount(&other))
.expect("addition operation overflow");
*self = <Self as $crate::BaseMoney<C>>::from_decimal(ret);
}
}
impl<C> ::std::ops::SubAssign for $T<C>
where
C: $crate::Currency,
{
fn sub_assign(&mut self, other: Self) {
let ret = $crate::BaseMoney::amount(self)
.checked_sub($crate::BaseMoney::amount(&other))
.expect("subtraction operation overflow");
*self = <Self as $crate::BaseMoney<C>>::from_decimal(ret);
}
}
impl<C> ::std::ops::Neg for $T<C>
where
C: $crate::Currency,
{
type Output = Self;
fn neg(self) -> Self::Output {
<Self as $crate::BaseMoney<C>>::from_decimal(-$crate::BaseMoney::amount(&self))
}
}
impl<C> ::std::ops::Add<$crate::Decimal> for $T<C>
where
C: $crate::Currency,
{
type Output = Self;
fn add(self, rhs: $crate::Decimal) -> Self::Output {
let ret = $crate::BaseMoney::amount(&self)
.checked_add(rhs)
.expect("addition operation overflow");
<Self as $crate::BaseMoney<C>>::from_decimal(ret)
}
}
impl<C> ::std::ops::Sub<$crate::Decimal> for $T<C>
where
C: $crate::Currency,
{
type Output = Self;
fn sub(self, rhs: $crate::Decimal) -> Self::Output {
let ret = $crate::BaseMoney::amount(&self)
.checked_sub(rhs)
.expect("subtraction operation overflow");
<Self as $crate::BaseMoney<C>>::from_decimal(ret)
}
}
impl<C> ::std::ops::Mul<$crate::Decimal> for $T<C>
where
C: $crate::Currency,
{
type Output = Self;
fn mul(self, rhs: $crate::Decimal) -> Self::Output {
let ret = $crate::BaseMoney::amount(&self)
.checked_mul(rhs)
.expect("multiplication operation overflow");
<Self as $crate::BaseMoney<C>>::from_decimal(ret)
}
}
impl<C> ::std::ops::Div<$crate::Decimal> for $T<C>
where
C: $crate::Currency,
{
type Output = Self;
fn div(self, rhs: $crate::Decimal) -> Self::Output {
let ret = $crate::BaseMoney::amount(&self)
.checked_div(rhs)
.expect("division operation overflow");
<Self as $crate::BaseMoney<C>>::from_decimal(ret)
}
}
impl<C> ::std::ops::Add<$T<C>> for $crate::Decimal
where
C: $crate::Currency,
{
type Output = $T<C>;
fn add(self, rhs: $T<C>) -> Self::Output {
let ret = self
.checked_add($crate::BaseMoney::amount(&rhs))
.expect("addition operation overflow");
<$T<C> as $crate::BaseMoney<C>>::from_decimal(ret)
}
}
impl<C> ::std::ops::Mul<$T<C>> for $crate::Decimal
where
C: $crate::Currency,
{
type Output = $T<C>;
fn mul(self, rhs: $T<C>) -> Self::Output {
let ret = self
.checked_mul($crate::BaseMoney::amount(&rhs))
.expect("multiplication operation overflow");
<$T<C> as $crate::BaseMoney<C>>::from_decimal(ret)
}
}
impl<C> ::std::ops::Rem<$crate::Decimal> for $T<C>
where
C: $crate::Currency,
{
type Output = $T<C>;
fn rem(self, rhs: $crate::Decimal) -> Self::Output {
let ret = $crate::BaseMoney::amount(&self)
.checked_rem(rhs)
.expect("remainder operation failed");
<$T<C> as $crate::BaseMoney<C>>::from_decimal(ret)
}
}
};
}
impl_money_ops!(Money);
#[cfg(feature = "raw_money")]
use crate::{BaseOps, RawMoney};
#[cfg(feature = "raw_money")]
impl_money_ops!(RawMoney);
use crate::Currency;
use std::ops::{Add, Sub};
#[cfg(feature = "raw_money")]
impl<C: Currency> Add<RawMoney<C>> for Money<C> {
type Output = Money<C>;
fn add(self, rhs: RawMoney<C>) -> Self::Output {
self.checked_add(rhs)
.expect("addition operation overflowed")
}
}
#[cfg(feature = "raw_money")]
impl<C: Currency> Add<Money<C>> for RawMoney<C> {
type Output = RawMoney<C>;
fn add(self, rhs: Money<C>) -> Self::Output {
self.checked_add(rhs)
.expect("addition operation overflowed")
}
}
#[cfg(feature = "raw_money")]
impl<C: Currency> Sub<RawMoney<C>> for Money<C> {
type Output = Money<C>;
fn sub(self, rhs: RawMoney<C>) -> Self::Output {
self.checked_sub(rhs)
.expect("substraction operation overflowed")
}
}
#[cfg(feature = "raw_money")]
impl<C: Currency> Sub<Money<C>> for RawMoney<C> {
type Output = RawMoney<C>;
fn sub(self, rhs: Money<C>) -> Self::Output {
self.checked_sub(rhs)
.expect("substraction operation overflowed")
}
}