Skip to main content

rex_shared/
models.rs

1use chrono::NaiveTime;
2use std::cmp::Ordering;
3use std::fmt;
4use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
5
6pub const LAST_POSSIBLE_TIME: NaiveTime =
7    NaiveTime::from_hms_nano_opt(23, 59, 59, 999_999_999).unwrap();
8
9impl Cent {
10    #[must_use]
11    pub fn percent_change(self, previous: Cent) -> Option<f64> {
12        if previous.0 == 0 {
13            None
14        } else {
15            let cur = self.0 as f64;
16            let prev = previous.0 as f64;
17            Some(((cur - prev) / prev) * 100.0)
18        }
19    }
20}
21
22impl Add<i64> for Cent {
23    type Output = Cent;
24
25    fn add(self, rhs: i64) -> Self::Output {
26        Cent(self.0 + rhs)
27    }
28}
29
30impl Sub<i64> for Cent {
31    type Output = Cent;
32
33    fn sub(self, rhs: i64) -> Self::Output {
34        Cent(self.0 - rhs)
35    }
36}
37
38impl Mul<i64> for Cent {
39    type Output = Cent;
40
41    fn mul(self, rhs: i64) -> Self::Output {
42        Cent(self.0 * rhs)
43    }
44}
45
46impl AddAssign<i64> for Cent {
47    fn add_assign(&mut self, rhs: i64) {
48        self.0 += rhs;
49    }
50}
51
52impl SubAssign<i64> for Cent {
53    fn sub_assign(&mut self, rhs: i64) {
54        self.0 -= rhs;
55    }
56}
57
58impl SubAssign for Cent {
59    fn sub_assign(&mut self, rhs: Self) {
60        self.0 -= rhs.0;
61    }
62}
63
64impl AddAssign for Cent {
65    fn add_assign(&mut self, other: Self) {
66        self.0 += other.0;
67    }
68}
69
70impl Div<f64> for Dollar {
71    type Output = Dollar;
72
73    fn div(self, rhs: f64) -> Self::Output {
74        Dollar(self.0 / rhs)
75    }
76}
77
78impl AddAssign<Cent> for i64 {
79    fn add_assign(&mut self, rhs: Cent) {
80        *self += rhs.0;
81    }
82}
83
84impl PartialEq<Cent> for i64 {
85    fn eq(&self, other: &Cent) -> bool {
86        *self == other.0
87    }
88}
89
90impl SubAssign<Cent> for i64 {
91    fn sub_assign(&mut self, rhs: Cent) {
92        *self -= rhs.0;
93    }
94}
95
96impl PartialEq<i64> for Cent {
97    fn eq(&self, other: &i64) -> bool {
98        self.0 == *other
99    }
100}
101
102impl PartialEq for Cent {
103    fn eq(&self, other: &Self) -> bool {
104        self.0 == other.0
105    }
106}
107
108impl PartialOrd for Cent {
109    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
110        self.0.partial_cmp(&other.0)
111    }
112}
113
114impl PartialOrd<i64> for Cent {
115    fn partial_cmp(&self, other: &i64) -> Option<Ordering> {
116        self.0.partial_cmp(other)
117    }
118}
119
120impl fmt::Display for Dollar {
121    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122        write!(f, "{:.2}", self.0)
123    }
124}
125
126#[derive(Debug, Clone, Copy, Default)]
127pub struct Cent(i64);
128
129#[derive(Debug, Clone, Copy, Default)]
130pub struct Dollar(f64);
131
132impl Cent {
133    #[must_use]
134    pub fn new(value: i64) -> Self {
135        Self(value)
136    }
137
138    #[must_use]
139    pub fn dollar(&self) -> Dollar {
140        Dollar::new(self.0 as f64 / 100.0)
141    }
142
143    #[must_use]
144    pub fn value(&self) -> i64 {
145        self.0
146    }
147}
148
149impl Dollar {
150    #[must_use]
151    pub fn new(value: f64) -> Self {
152        Self(value)
153    }
154
155    #[must_use]
156    pub fn value(&self) -> f64 {
157        self.0
158    }
159
160    #[must_use]
161    pub fn cent(&self) -> Cent {
162        Cent::new((self.0 * 100.0).round() as i64)
163    }
164}