decimal.rs (3775B)
1 use core::fmt; 2 use core::ops::{Add, Div, Mul, Sub}; 3 use core::str::FromStr; 4 use rust_decimal::Decimal; 5 use rust_decimal::prelude::ToPrimitive; 6 7 #[cfg(all(feature = "serde", not(feature = "std")))] 8 use alloc::string::String; 9 #[cfg(not(feature = "std"))] 10 use alloc::{format, string::ToString}; 11 12 #[cfg(feature = "serde")] 13 use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as DeError}; 14 15 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] 16 pub struct RadrootsCoreDecimal(pub Decimal); 17 18 impl RadrootsCoreDecimal { 19 pub const ZERO: Self = Self(Decimal::ZERO); 20 pub const ONE: Self = Self(Decimal::ONE); 21 22 #[inline] 23 pub fn is_zero(&self) -> bool { 24 self.0.is_zero() 25 } 26 #[inline] 27 pub fn is_sign_negative(&self) -> bool { 28 self.0.is_sign_negative() 29 } 30 #[inline] 31 pub fn rescale(&mut self, scale: u32) { 32 self.0.rescale(scale); 33 } 34 #[inline] 35 pub fn normalize(&self) -> Decimal { 36 self.0.normalize() 37 } 38 39 #[inline] 40 pub fn scale(&self) -> u32 { 41 self.0.scale() 42 } 43 44 #[inline] 45 pub fn from_str_exact(s: &str) -> Result<Self, rust_decimal::Error> { 46 Decimal::from_str_exact(s).map(Self) 47 } 48 49 #[inline] 50 pub fn from_f64_display(n: f64) -> Result<Self, rust_decimal::Error> { 51 let s = format!("{:.17}", n); 52 Decimal::from_str(&s).map(Self) 53 } 54 #[inline] 55 pub fn to_f64_lossy(&self) -> Option<f64> { 56 self.0.to_f64() 57 } 58 59 #[inline] 60 pub fn to_u64_exact(&self) -> Option<u64> { 61 if self.0.fract().is_zero() { 62 self.0.to_u64() 63 } else { 64 None 65 } 66 } 67 } 68 69 #[cfg(feature = "serde")] 70 impl Serialize for RadrootsCoreDecimal { 71 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 72 serializer.serialize_str(&self.normalize().to_string()) 73 } 74 } 75 76 #[cfg(feature = "serde")] 77 impl<'de> Deserialize<'de> for RadrootsCoreDecimal { 78 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { 79 let s = String::deserialize(deserializer)?; 80 Decimal::from_str(&s) 81 .map(RadrootsCoreDecimal) 82 .map_err(D::Error::custom) 83 } 84 } 85 86 impl fmt::Display for RadrootsCoreDecimal { 87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 88 f.write_str(&self.normalize().to_string()) 89 } 90 } 91 92 impl From<Decimal> for RadrootsCoreDecimal { 93 fn from(d: Decimal) -> Self { 94 Self(d) 95 } 96 } 97 impl From<RadrootsCoreDecimal> for Decimal { 98 fn from(d: RadrootsCoreDecimal) -> Self { 99 d.0 100 } 101 } 102 impl From<u32> for RadrootsCoreDecimal { 103 fn from(v: u32) -> Self { 104 Self(Decimal::from(v)) 105 } 106 } 107 impl From<i32> for RadrootsCoreDecimal { 108 fn from(v: i32) -> Self { 109 Self(Decimal::from(v)) 110 } 111 } 112 impl From<u64> for RadrootsCoreDecimal { 113 fn from(v: u64) -> Self { 114 Self(Decimal::from(v)) 115 } 116 } 117 impl From<i64> for RadrootsCoreDecimal { 118 fn from(v: i64) -> Self { 119 Self(Decimal::from(v)) 120 } 121 } 122 123 impl Add for RadrootsCoreDecimal { 124 type Output = Self; 125 fn add(self, rhs: Self) -> Self { 126 Self(self.0 + rhs.0) 127 } 128 } 129 impl Sub for RadrootsCoreDecimal { 130 type Output = Self; 131 fn sub(self, rhs: Self) -> Self { 132 Self(self.0 - rhs.0) 133 } 134 } 135 impl Mul for RadrootsCoreDecimal { 136 type Output = Self; 137 fn mul(self, rhs: Self) -> Self { 138 Self(self.0 * rhs.0) 139 } 140 } 141 impl Div for RadrootsCoreDecimal { 142 type Output = Self; 143 fn div(self, rhs: Self) -> Self { 144 Self(self.0 / rhs.0) 145 } 146 } 147 148 impl FromStr for RadrootsCoreDecimal { 149 type Err = rust_decimal::Error; 150 fn from_str(s: &str) -> Result<Self, Self::Err> { 151 Decimal::from_str(s).map(RadrootsCoreDecimal) 152 } 153 }