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}