Skip to content

Commit

Permalink
feat: impl num_traits::Zero, num_traits::One and std::ops::Rem
Browse files Browse the repository at this point in the history
…for `Decimal` (#9)
  • Loading branch information
MathisWellmann authored Oct 18, 2024
1 parent abcf55d commit 18c9eac
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/cheats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,21 @@ impl_primitive!(u64);
impl_primitive!(i64);
impl_primitive!(u128);
impl_primitive!(i128);

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn scaling_factor() {
assert_eq!(<i32 as Cheats<0>>::SCALING_FACTOR, 1);
assert_eq!(<i32 as Cheats<1>>::SCALING_FACTOR, 10);
assert_eq!(<i32 as Cheats<2>>::SCALING_FACTOR, 100);
assert_eq!(<i32 as Cheats<3>>::SCALING_FACTOR, 1000);

assert_eq!(<i64 as Cheats<0>>::SCALING_FACTOR, 1);
assert_eq!(<i64 as Cheats<1>>::SCALING_FACTOR, 10);
assert_eq!(<i64 as Cheats<2>>::SCALING_FACTOR, 100);
assert_eq!(<i64 as Cheats<3>>::SCALING_FACTOR, 1000);
}
}
47 changes: 47 additions & 0 deletions src/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,37 @@ where
}
}

#[inline]
pub fn is_zero(&self) -> bool {
self.0 == I::ZERO
}
}

impl<I, const D: u8> num_traits::Zero for Decimal<I, D>
where
I: ScaledInteger<D>,
{
#[inline]
fn zero() -> Self {
Self(I::zero())
}

#[inline]
fn is_zero(&self) -> bool {
self.0.is_zero()
}
}

impl<I, const D: u8> num_traits::One for Decimal<I, D>
where
I: ScaledInteger<D>,
{
#[inline]
fn one() -> Self {
Self(I::one() * <I as crate::cheats::Cheats<D>>::SCALING_FACTOR)
}
}

impl<I, const D: u8> Add for Decimal<I, D>
where
I: ScaledInteger<D>,
Expand Down Expand Up @@ -123,12 +149,25 @@ where
}
}

impl<I, const D: u8> std::ops::Rem for Decimal<I, D>
where
I: ScaledInteger<D>,
{
type Output = Self;

#[inline]
fn rem(self, rhs: Self) -> Self::Output {
Self(self.0 % rhs.0)
}
}

impl<I, const D: u8> Neg for Decimal<I, D>
where
I: SignedScaledInteger<D>,
{
type Output = Self;

#[inline]
fn neg(self) -> Self::Output {
Decimal(self.0.checked_neg().unwrap())
}
Expand Down Expand Up @@ -189,6 +228,14 @@ mod tests {
macro_rules! test_basic_ops {
($underlying:ty, $decimals:literal) => {
paste! {
#[test]
fn [<num_traits_one_ $underlying _ $decimals _add>]() {
use num_traits::One;
assert_eq!(Decimal::<$underlying, $decimals>::one(), Decimal::try_from_scaled(1, 0).unwrap());
assert_eq!(Decimal::<$underlying, $decimals>::one(), Decimal::try_from_scaled(10, 1).unwrap());
assert_eq!(Decimal::<$underlying, $decimals>::one(), Decimal::try_from_scaled(100, 2).unwrap());
}

#[test]
fn [<$underlying _ $decimals _add>]() {
assert_eq!(
Expand Down

0 comments on commit 18c9eac

Please sign in to comment.