polyvalue/inner_types/
fixed.rs1use crate::Error;
2use fpdec::{CheckedAdd, CheckedDiv, CheckedMul, CheckedRem, CheckedSub, Decimal, Round};
3use serde::{Deserialize, Serialize};
4use std::{ops::Deref, str::FromStr};
5
6#[macro_export]
15macro_rules! fixed {
16 ($value:expr) => {
17 Fixed::from(fpdec::Dec!($value))
18 };
19}
20
21#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Clone, Serialize, Deserialize, Default)]
22pub struct BoxedDecimal(Box<Decimal>);
23impl BoxedDecimal {
24 pub fn new(value: Decimal) -> Self {
25 Self(Box::new(value))
26 }
27
28 pub fn inner(&self) -> &Decimal {
29 &self.0
30 }
31
32 pub fn inner_mut(&mut self) -> &mut Decimal {
33 &mut self.0
34 }
35
36 pub fn n_frac_digits(&self) -> u8 {
37 self.0.n_frac_digits()
38 }
39
40 pub fn trunc(&self) -> Self {
41 Self::new(self.0.trunc())
42 }
43
44 pub fn coefficient(&self) -> i128 {
45 self.0.coefficient()
46 }
47}
48
49impl From<BoxedDecimal> for f64 {
50 fn from(val: BoxedDecimal) -> Self {
51 (*val.0).into()
52 }
53}
54
55impl From<Decimal> for BoxedDecimal {
56 fn from(value: Decimal) -> Self {
57 Self::new(value)
58 }
59}
60
61impl FromStr for BoxedDecimal {
62 type Err = Error;
63 fn from_str(s: &str) -> Result<Self, Self::Err> {
64 Ok(Self::new(s.parse::<Decimal>()?))
65 }
66}
67
68impl std::fmt::Display for BoxedDecimal {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 self.0.fmt(f)
71 }
72}
73
74impl std::fmt::Debug for BoxedDecimal {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 self.0.fmt(f)
77 }
78}
79
80impl CheckedAdd for BoxedDecimal {
81 type Output = Option<Self>;
82 fn checked_add(self, rhs: Self) -> Self::Output {
83 self.0.checked_add(*rhs.0).map(Self::new)
84 }
85}
86impl CheckedSub for BoxedDecimal {
87 type Output = Option<Self>;
88 fn checked_sub(self, rhs: Self) -> Self::Output {
89 self.0.checked_sub(*rhs.0).map(Self::new)
90 }
91}
92impl CheckedMul for BoxedDecimal {
93 type Output = Option<Self>;
94 fn checked_mul(self, rhs: Self) -> Self::Output {
95 self.0.checked_mul(*rhs.0).map(Self::new)
96 }
97}
98impl CheckedDiv for BoxedDecimal {
99 type Output = Option<Self>;
100 fn checked_div(self, rhs: Self) -> Self::Output {
101 self.0.checked_div(*rhs.0).map(Self::new)
102 }
103}
104impl CheckedRem for BoxedDecimal {
105 type Output = Option<Self>;
106 fn checked_rem(self, rhs: Self) -> Self::Output {
107 self.0.checked_rem(*rhs.0).map(Self::new)
108 }
109}
110impl Round for BoxedDecimal {
111 fn round(self, n_frac_digits: i8) -> Self {
112 Self::new(self.0.round(n_frac_digits))
113 }
114
115 fn checked_round(self, n_frac_digits: i8) -> Option<Self> {
116 self.0.checked_round(n_frac_digits).map(Self::new)
117 }
118}
119impl std::ops::Neg for BoxedDecimal {
120 type Output = Self;
121 fn neg(self) -> Self::Output {
122 Self::new(-*(self.0))
123 }
124}
125
126impl Deref for BoxedDecimal {
127 type Target = Decimal;
128 fn deref(&self) -> &Self::Target {
129 &self.0
130 }
131}