From aee8580c084084b612b3435c3d5a768bf5f4c865 Mon Sep 17 00:00:00 2001 From: Wojciech Date: Wed, 11 Oct 2023 14:45:37 +0200 Subject: [PATCH] Add checked_div implementation --- decimal_core/src/checked_ops.rs | 28 ++++++++++++++++++++++++++++ src/traits.rs | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/decimal_core/src/checked_ops.rs b/decimal_core/src/checked_ops.rs index 7af8f02..b884e33 100644 --- a/decimal_core/src/checked_ops.rs +++ b/decimal_core/src/checked_ops.rs @@ -24,6 +24,17 @@ pub fn generate_checked_ops(characteristics: DecimalCharacteristics) -> proc_mac .ok_or_else(|| "checked_sub: (self - rhs) subtraction underflow")? )) } + + fn checked_div(self, rhs: Self) -> std::result::Result { + Ok(Self::new( + self.get() + .checked_mul(Self::one()) + .ok_or_else(|| "checked_div: (self * Self::one()) multiplication overflow")? + .checked_div(rhs.get()) + .ok_or_else(|| "checked_div: ((self * Self::one()) / rhs) division by zero")? + ) + ) + } } #[cfg(test)] @@ -54,6 +65,23 @@ pub fn generate_checked_ops(characteristics: DecimalCharacteristics) -> proc_mac assert_eq!(a.checked_sub(b), Ok(#struct_name::new(24))); } + #[test] + fn test_checked_div() { + let a = #struct_name::new(2); + let b = #struct_name::new(#struct_name::one()); + + assert_eq!(a.checked_div(b), Ok(#struct_name::new(2))); + } + + #[test] + fn test_0_checked_div() { + let a = #struct_name::new(47); + let b = #struct_name::new(0); + let result = a.checked_div(b); + + assert!(result.is_err()); + } + #[test] fn test_underflow_checked_sub() { let min = #struct_name::new(0); diff --git a/src/traits.rs b/src/traits.rs index 9cc8389..9795748 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -39,7 +39,6 @@ pub trait Factories: Sized { fn from_scale_up(integer: T, scale: u8) -> Self; } - pub trait BetweenDecimals: Sized { fn from_decimal(other: T) -> Self; fn checked_from_decimal(other: T) -> std::result::Result; @@ -69,4 +68,5 @@ pub trait ByNumber: Sized { pub trait CheckedOps: Sized { fn checked_add(self, rhs: Self) -> std::result::Result; fn checked_sub(self, rhs: Self) -> std::result::Result; + fn checked_div(self, rhs: Self) -> std::result::Result; }