Skip to content

Commit

Permalink
refactor: streamline arithmetic traits with macros (#95)
Browse files Browse the repository at this point in the history
Consolidated repetitive implementations of `Add`, `Sub`, `Mul`, and `Div` into reusable macros for `FractionLike`, reducing code duplication and improving maintainability. This change ensures uniform functionality across operations and simplifies future updates.
  • Loading branch information
shuhuiluo authored Jan 5, 2025
1 parent 5e6f032 commit 5c1c453
Showing 1 changed file with 60 additions and 126 deletions.
186 changes: 60 additions & 126 deletions src/entities/fractions/fraction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,141 +225,75 @@ impl<M: PartialEq> PartialOrd<Self> for FractionLike<M> {
}
}

impl<M: Clone> Add for FractionLike<M> {
type Output = Self;

#[inline]
fn add(self, other: Self) -> Self::Output {
if self.denominator == other.denominator {
FractionBase::new(
self.numerator + other.numerator,
self.denominator,
self.meta,
)
} else {
FractionBase::new(
self.numerator * other.denominator + other.numerator * self.denominator,
self.denominator * other.denominator,
self.meta,
)
macro_rules! impl_add_sub {
($trait:ident, $method:ident, $op:tt, $Rhs:ty) => {
impl<M: Clone> $trait<$Rhs> for FractionLike<M> {
type Output = Self;

#[inline]
fn $method(self, other: $Rhs) -> Self::Output {
if self.denominator == other.denominator {
FractionBase::new(
self.numerator $op other.numerator,
self.denominator,
self.meta,
)
} else {
FractionBase::new(
self.numerator * other.denominator $op other.numerator * self.denominator,
self.denominator * other.denominator,
self.meta,
)
}
}
}
}
};
}

impl<M: Clone> Add<&Self> for FractionLike<M> {
type Output = Self;

#[inline]
fn add(self, other: &Self) -> Self::Output {
if self.denominator == other.denominator {
FractionBase::new(
self.numerator + other.numerator,
self.denominator,
self.meta,
)
} else {
FractionBase::new(
self.numerator * other.denominator + other.numerator * self.denominator,
self.denominator * other.denominator,
self.meta,
)
impl_add_sub!(Add, add, +, Self);
impl_add_sub!(Add, add, +, &Self);
impl_add_sub!(Sub, sub, -, Self);
impl_add_sub!(Sub, sub, -, &Self);

macro_rules! impl_mul {
($trait:ident, $method:ident, $Rhs:ty) => {
impl<M: Clone> $trait<$Rhs> for FractionLike<M> {
type Output = Self;

#[inline]
fn $method(self, other: $Rhs) -> Self::Output {
FractionBase::new(
self.numerator * other.numerator,
self.denominator * other.denominator,
self.meta,
)
}
}
}
};
}

impl<M: Clone> Sub for FractionLike<M> {
type Output = Self;

#[inline]
fn sub(self, other: Self) -> Self::Output {
if self.denominator == other.denominator {
FractionBase::new(
self.numerator - other.numerator,
self.denominator,
self.meta,
)
} else {
FractionBase::new(
self.numerator * other.denominator - other.numerator * self.denominator,
self.denominator * other.denominator,
self.meta,
)
impl_mul!(Mul, mul, Self);
impl_mul!(Mul, mul, &Self);

macro_rules! impl_div {
($trait:ident, $method:ident, $Rhs:ty) => {
impl<M: Clone> $trait<$Rhs> for FractionLike<M> {
type Output = Self;

#[inline]
fn $method(self, other: $Rhs) -> Self::Output {
FractionBase::new(
self.numerator * other.denominator,
self.denominator * other.numerator,
self.meta,
)
}
}
}
}

impl<M: Clone> Sub<&Self> for FractionLike<M> {
type Output = Self;

#[inline]
fn sub(self, other: &Self) -> Self::Output {
if self.denominator == other.denominator {
FractionBase::new(
self.numerator - other.numerator,
self.denominator,
self.meta,
)
} else {
FractionBase::new(
self.numerator * other.denominator - other.numerator * self.denominator,
self.denominator * other.denominator,
self.meta,
)
}
}
}

impl<M: Clone> Mul for FractionLike<M> {
type Output = Self;

#[inline]
fn mul(self, other: Self) -> Self::Output {
FractionBase::new(
self.numerator * other.numerator,
self.denominator * other.denominator,
self.meta,
)
}
}

impl<M: Clone> Mul<&Self> for FractionLike<M> {
type Output = Self;

#[inline]
fn mul(self, other: &Self) -> Self::Output {
FractionBase::new(
self.numerator * other.numerator,
self.denominator * other.denominator,
self.meta,
)
}
};
}

impl<M: Clone> Div for FractionLike<M> {
type Output = Self;

#[inline]
fn div(self, other: Self) -> Self::Output {
FractionBase::new(
self.numerator * other.denominator,
self.denominator * other.numerator,
self.meta,
)
}
}

impl<M: Clone> Div<&Self> for FractionLike<M> {
type Output = Self;

#[inline]
fn div(self, other: &Self) -> Self::Output {
FractionBase::new(
self.numerator * other.denominator,
self.denominator * other.numerator,
self.meta,
)
}
}
impl_div!(Div, div, Self);
impl_div!(Div, div, &Self);

#[cfg(test)]
mod tests {
Expand Down

0 comments on commit 5c1c453

Please sign in to comment.