1use serde::{Deserialize, Serialize};
8use std::fmt;
9
10#[derive(Clone, Debug, Serialize, Deserialize)]
24pub struct PaddedInt {
25 value: i64,
26 formatted: String,
27}
28
29impl PaddedInt {
30 pub fn new(s: &str) -> Self {
32 let value = s.parse::<i64>().unwrap_or(0);
33 Self {
34 value,
35 formatted: s.to_string(),
36 }
37 }
38
39 #[must_use]
41 pub fn value(&self) -> i64 {
42 self.value
43 }
44}
45
46impl From<i64> for PaddedInt {
47 fn from(v: i64) -> Self {
48 Self {
49 value: v,
50 formatted: v.to_string(),
51 }
52 }
53}
54
55impl From<i32> for PaddedInt {
56 fn from(v: i32) -> Self {
57 Self::from(v as i64)
58 }
59}
60
61impl fmt::Display for PaddedInt {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 write!(f, "{}", self.formatted)
64 }
65}
66
67impl PartialEq for PaddedInt {
68 fn eq(&self, other: &Self) -> bool {
69 self.value == other.value
70 }
71}
72
73impl Eq for PaddedInt {}
74
75impl PartialOrd for PaddedInt {
76 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
77 Some(self.cmp(other))
78 }
79}
80
81impl Ord for PaddedInt {
82 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
83 self.value.cmp(&other.value)
84 }
85}
86
87impl std::hash::Hash for PaddedInt {
88 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
89 self.value.hash(state);
90 }
91}
92
93impl PartialEq<i64> for PaddedInt {
94 fn eq(&self, other: &i64) -> bool {
95 self.value == *other
96 }
97}
98
99impl PartialEq<PaddedInt> for i64 {
100 fn eq(&self, other: &PaddedInt) -> bool {
101 *self == other.value
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn test_padded_int() {
111 let p = PaddedInt::new("02");
112 assert_eq!(p.value(), 2);
113 assert_eq!(p.to_string(), "02");
114 assert_eq!(p, PaddedInt::from(2));
115 assert!(p == 2i64);
116
117 let p1 = PaddedInt::new("001");
118 let p2 = PaddedInt::new("01");
119 assert_eq!(p1, p2);
120 assert_eq!(p1.to_string(), "001");
121 assert_eq!(p2.to_string(), "01");
122 }
123}