lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

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 }