/// Decimal Conversion Helpers for Tests /// /// Provides utilities to safely convert between f64 and Decimal types in test code. /// /// Production code should use Decimal throughout, but tests often need to work with /// floating point values for convenience. use rust_decimal::Decimal; pub use rust_decimal_macros::dec; /// Trait to convert f64 to Decimal safely pub trait ToDecimal { fn to_decimal(self) -> Decimal; } impl ToDecimal for f64 { /// Convert f64 to Decimal, returning ZERO on failure fn to_decimal(self) -> Decimal { Decimal::from_f64_retain(self).unwrap_or(Decimal::ZERO) } } impl ToDecimal for i32 { /// Convert i32 to Decimal safely fn to_decimal(self) -> Decimal { Decimal::from(self) } } impl ToDecimal for i64 { /// Convert i64 to Decimal safely fn to_decimal(self) -> Decimal { Decimal::from(self) } } impl ToDecimal for u32 { /// Convert u32 to Decimal safely fn to_decimal(self) -> Decimal { Decimal::from(self) } } impl ToDecimal for u64 { /// Convert u64 to Decimal safely fn to_decimal(self) -> Decimal { Decimal::from(self) } } /// Convert f64 to Decimal (convenience function) pub fn decimal(f: f64) -> Decimal { f.to_decimal() } /// Convert f64 to Decimal with explicit error message pub fn decimal_or_panic(f: f64, msg: &str) -> Decimal { Decimal::from_f64_retain(f).expect(msg) } #[cfg(test)] mod tests { use super::*; #[test] fn test_f64_to_decimal() { let d = 100.5.to_decimal(); assert_eq!(d.to_string(), "100.5"); let d2 = decimal(200.75); assert_eq!(d2.to_string(), "200.75"); } #[test] fn test_integer_to_decimal() { let d1 = 100i32.to_decimal(); assert_eq!(d1, Decimal::from(100)); let d2 = 1000u64.to_decimal(); assert_eq!(d2, Decimal::from(1000)); } #[test] fn test_nan_returns_zero() { let d = f64::NAN.to_decimal(); assert_eq!(d, Decimal::ZERO); } #[test] fn test_infinity_returns_zero() { let d = f64::INFINITY.to_decimal(); assert_eq!(d, Decimal::ZERO); } }