1use serde::Serialize;
2
3/// A number of cents.
4#[derive(
5 Debug,
6 PartialEq,
7 Eq,
8 PartialOrd,
9 Ord,
10 Hash,
11 Clone,
12 Copy,
13 derive_more::Add,
14 derive_more::AddAssign,
15 derive_more::Sub,
16 derive_more::SubAssign,
17 Serialize,
18)]
19pub struct Cents(pub u32);
20
21impl Cents {
22 pub const ZERO: Self = Self(0);
23
24 pub const fn new(cents: u32) -> Self {
25 Self(cents)
26 }
27
28 pub const fn from_dollars(dollars: u32) -> Self {
29 Self(dollars * 100)
30 }
31
32 pub fn saturating_sub(self, other: Cents) -> Self {
33 Self(self.0.saturating_sub(other.0))
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use pretty_assertions::assert_eq;
40
41 use super::*;
42
43 #[test]
44 fn test_cents_new() {
45 assert_eq!(Cents::new(50), Cents(50));
46 }
47
48 #[test]
49 fn test_cents_from_dollars() {
50 assert_eq!(Cents::from_dollars(1), Cents(100));
51 assert_eq!(Cents::from_dollars(5), Cents(500));
52 }
53
54 #[test]
55 fn test_cents_zero() {
56 assert_eq!(Cents::ZERO, Cents(0));
57 }
58
59 #[test]
60 fn test_cents_add() {
61 assert_eq!(Cents(50) + Cents(30), Cents(80));
62 }
63
64 #[test]
65 fn test_cents_add_assign() {
66 let mut cents = Cents(50);
67 cents += Cents(30);
68 assert_eq!(cents, Cents(80));
69 }
70
71 #[test]
72 fn test_cents_saturating_sub() {
73 assert_eq!(Cents(50).saturating_sub(Cents(30)), Cents(20));
74 assert_eq!(Cents(30).saturating_sub(Cents(50)), Cents(0));
75 }
76
77 #[test]
78 fn test_cents_ordering() {
79 assert!(Cents(50) > Cents(30));
80 assert!(Cents(30) < Cents(50));
81 assert_eq!(Cents(50), Cents(50));
82 }
83}