1use {
2 super::*,
3 std::{
4 cmp::{PartialEq, PartialOrd},
5 ops::{Add, AddAssign, Div, Rem, Sub, SubAssign},
6 },
7};
8
9#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Default, Serialize, Deserialize)]
10pub struct Lot(pub u128);
11
12impl Lot {
13 #[cfg(test)]
14 const MAX: Self = Self(u128::MAX);
15
16 pub(super) fn n(self) -> u128 {
17 self.0
18 }
19
20 fn checked_add(self, rhs: Self) -> Option<Self> {
21 Some(Self(self.0.checked_add(rhs.0)?))
22 }
23
24 fn checked_sub(self, rhs: Self) -> Option<Self> {
25 Some(Self(self.0.checked_sub(rhs.0)?))
26 }
27}
28
29impl TryFrom<Lot> for usize {
30 type Error = <usize as TryFrom<u128>>::Error;
31 fn try_from(lot: Lot) -> Result<Self, Self::Error> {
32 usize::try_from(lot.0)
33 }
34}
35
36impl Add for Lot {
37 type Output = Self;
38 fn add(self, other: Self) -> Self::Output {
39 self.checked_add(other).expect("lot overflow")
40 }
41}
42
43impl AddAssign for Lot {
44 fn add_assign(&mut self, other: Self) {
45 *self = *self + other;
46 }
47}
48
49impl Add<u128> for Lot {
50 type Output = Self;
51 fn add(self, other: u128) -> Self::Output {
52 self + Lot(other)
53 }
54}
55
56impl AddAssign<u128> for Lot {
57 fn add_assign(&mut self, other: u128) {
58 *self += Lot(other);
59 }
60}
61
62impl Sub for Lot {
63 type Output = Self;
64 fn sub(self, other: Self) -> Self::Output {
65 self.checked_sub(other).expect("lot underflow")
66 }
67}
68
69impl SubAssign for Lot {
70 fn sub_assign(&mut self, other: Self) {
71 *self = *self - other;
72 }
73}
74
75impl Div<u128> for Lot {
76 type Output = Self;
77 fn div(self, other: u128) -> Self::Output {
78 Lot(self.0 / other)
79 }
80}
81
82impl Rem<u128> for Lot {
83 type Output = Self;
84 fn rem(self, other: u128) -> Self::Output {
85 Lot(self.0 % other)
86 }
87}
88
89impl PartialEq<u128> for Lot {
90 fn eq(&self, other: &u128) -> bool {
91 self.0 == *other
92 }
93}
94
95impl PartialOrd<u128> for Lot {
96 fn partial_cmp(&self, other: &u128) -> Option<std::cmp::Ordering> {
97 self.0.partial_cmp(other)
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 #[should_panic(expected = "lot overflow")]
107 fn add() {
108 let _ = Lot::MAX + 1;
109 }
110
111 #[test]
112 #[should_panic(expected = "lot overflow")]
113 fn add_assign() {
114 let mut l = Lot::MAX;
115 l += Lot(1);
116 }
117
118 #[test]
119 #[should_panic(expected = "lot overflow")]
120 fn add_u128() {
121 let _ = Lot::MAX + 1;
122 }
123
124 #[test]
125 #[should_panic(expected = "lot overflow")]
126 fn add_assign_u128() {
127 let mut l = Lot::MAX;
128 l += 1;
129 }
130
131 #[test]
132 #[should_panic(expected = "lot underflow")]
133 fn sub() {
134 let _ = Lot(0) - Lot(1);
135 }
136
137 #[test]
138 #[should_panic(expected = "lot underflow")]
139 fn sub_assign() {
140 let mut l = Lot(0);
141 l -= Lot(1);
142 }
143
144 #[test]
145 fn div() {
146 assert_eq!(Lot(100) / 2, Lot(50));
147 }
148
149 #[test]
150 fn rem() {
151 assert_eq!(Lot(77) % 8, Lot(5));
152 }
153
154 #[test]
155 fn partial_eq() {
156 assert_eq!(Lot(100), 100);
157 }
158
159 #[test]
160 fn partial_ord() {
161 assert!(Lot(100) > 10);
162 }
163}