From 38f3962c225b598cac0a8d5a82c986a088041d8f Mon Sep 17 00:00:00 2001 From: Serge Latyntsev Date: Sun, 4 Dec 2022 13:01:17 +1300 Subject: [PATCH] Ord trait (#76) * Ord trait and tests for fraction and decimal --- CHANGELOG.md | 5 ++ src/decimal/mod.rs | 1 + src/fraction/generic_fraction.rs | 80 +++++++++++++++++++++++++------- 3 files changed, 70 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04032e24..6b191856 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log +## [0.12.2] - 2022-12-04 + +### Added + - `Ord` trait implementation for GenericFraction and GenericDecimal (special thanks to Hsingai Tigris Altaica aka DrAlta) + ## [0.12.1] - 2022-10-18 ### Added diff --git a/src/decimal/mod.rs b/src/decimal/mod.rs index 6bae53ce..cf5409cf 100644 --- a/src/decimal/mod.rs +++ b/src/decimal/mod.rs @@ -447,6 +447,7 @@ where } dec_impl!(impl_trait_cmp; PartialOrd; partial_cmp; Option); +dec_impl!(impl_trait_cmp; Ord; cmp; Ordering); impl PartialEq for GenericDecimal where diff --git a/src/fraction/generic_fraction.rs b/src/fraction/generic_fraction.rs index 98cd8f5f..8a346d37 100644 --- a/src/fraction/generic_fraction.rs +++ b/src/fraction/generic_fraction.rs @@ -517,24 +517,18 @@ impl PartialOrd for GenericFraction { } impl Ord for GenericFraction { - fn cmp(&self, other: &Self) -> Ordering { - if *self == GenericFraction::NaN { - if *other == GenericFraction::NaN { - Ordering::Equal - } else { - Ordering::Less - } - } else { - if *other == GenericFraction::NaN { - Ordering::Greater - } else { - self.partial_cmp(other).expect("Well when I wrote this the only way partial_cmp() would return None was if one of the argument was NaN, which they weren't in this case.") - } - } - } + fn cmp(&self, other: &Self) -> Ordering { + match (self, other) { + (GenericFraction::NaN, GenericFraction::NaN) => Ordering::Equal, + (GenericFraction::NaN, _) => Ordering::Less, + (_, GenericFraction::NaN) => Ordering::Greater, + (_, _) => self + .partial_cmp(other) + .expect("All NaN has been tested above"), + } + } } - impl Neg for GenericFraction { type Output = GenericFraction; @@ -1259,6 +1253,7 @@ mod tests { use super::{CheckedAdd, CheckedDiv, CheckedMul, CheckedSub}; + use std::cmp::Ordering; use std::collections::HashMap; use std::hash::{Hash, Hasher}; use std::num::FpCategory; @@ -1701,6 +1696,59 @@ mod tests { assert!(Frac::zero() < Frac::new(1u8, 2u8)); } + #[test] + fn cmp() { + /* CMP */ + let nan = Frac::nan(); + let neg_inf = Frac::neg_infinity(); + let neg_one = Frac::one() * -1; + let zero = Frac::zero(); + let one = Frac::one(); + let inf = Frac::infinity(); + + assert_eq!(nan.cmp(&nan), Ordering::Equal); + assert_eq!(nan.cmp(&neg_inf), Ordering::Less); + assert_eq!(nan.cmp(&neg_one), Ordering::Less); + assert_eq!(nan.cmp(&zero), Ordering::Less); + assert_eq!(nan.cmp(&one), Ordering::Less); + assert_eq!(nan.cmp(&inf), Ordering::Less); + + assert_eq!(neg_inf.cmp(&nan), Ordering::Greater); + assert_eq!(neg_inf.cmp(&neg_inf), Ordering::Equal); + assert_eq!(neg_inf.cmp(&neg_one), Ordering::Less); + assert_eq!(neg_inf.cmp(&zero), Ordering::Less); + assert_eq!(neg_inf.cmp(&one), Ordering::Less); + assert_eq!(neg_inf.cmp(&inf), Ordering::Less); + + assert_eq!(neg_one.cmp(&nan), Ordering::Greater); + assert_eq!(neg_one.cmp(&neg_inf), Ordering::Greater); + assert_eq!(neg_one.cmp(&neg_one), Ordering::Equal); + assert_eq!(neg_one.cmp(&zero), Ordering::Less); + assert_eq!(neg_one.cmp(&one), Ordering::Less); + assert_eq!(neg_one.cmp(&inf), Ordering::Less); + + assert_eq!(zero.cmp(&nan), Ordering::Greater); + assert_eq!(zero.cmp(&neg_inf), Ordering::Greater); + assert_eq!(zero.cmp(&neg_one), Ordering::Greater); + assert_eq!(zero.cmp(&zero), Ordering::Equal); + assert_eq!(zero.cmp(&one), Ordering::Less); + assert_eq!(zero.cmp(&inf), Ordering::Less); + + assert_eq!(one.cmp(&nan), Ordering::Greater); + assert_eq!(one.cmp(&neg_inf), Ordering::Greater); + assert_eq!(one.cmp(&neg_one), Ordering::Greater); + assert_eq!(one.cmp(&zero), Ordering::Greater); + assert_eq!(one.cmp(&one), Ordering::Equal); + assert_eq!(one.cmp(&inf), Ordering::Less); + + assert_eq!(inf.cmp(&nan), Ordering::Greater); + assert_eq!(inf.cmp(&neg_inf), Ordering::Greater); + assert_eq!(inf.cmp(&neg_one), Ordering::Greater); + assert_eq!(inf.cmp(&zero), Ordering::Greater); + assert_eq!(inf.cmp(&one), Ordering::Greater); + assert_eq!(inf.cmp(&inf), Ordering::Equal); + } + #[test] fn from_str() { assert_eq!(Ok(Frac::zero()), Frac::from_str("0"));