1use serde::de;
2use serde::de::Visitor;
3use serde::Deserialize;
4use serde::Deserializer;
5use serde::Serialize;
6use serde::Serializer;
7use std::fmt;
8
9#[derive(PartialEq, Eq, Hash, Clone, Debug)]
11pub enum Max {
12 Unbounded,
13 IntMax(usize),
14}
15
16impl Max {
17 pub fn minus(&self, n: usize) -> Max {
18 match self {
19 Max::Unbounded => Max::Unbounded,
20 Max::IntMax(0) => Max::IntMax(0),
21 Max::IntMax(m) => {
22 let max = if m > &n { m - n } else { 0 };
23 Max::IntMax(max)
24 }
25 }
26 }
27
28 pub fn greater_or_equal(&self, n: usize) -> bool {
29 match self {
30 Max::IntMax(max) => *max >= n,
31 Max::Unbounded => true,
32 }
33 }
34}
35
36impl From<usize> for Max {
37 fn from(m: usize) -> Self {
38 Max::IntMax(m)
39 }
40}
41
42impl From<i32> for Max {
43 fn from(m: i32) -> Self {
44 Max::IntMax(m as usize)
45 }
46}
47
48impl From<i64> for Max {
49 fn from(m: i64) -> Self {
50 match m {
51 -1 => Max::Unbounded,
52 n if n > 0 => Max::IntMax(n as usize),
53 _ => panic!("Error converting i64 to Max, value {m} < -1"),
54 }
55 }
56}
57
58impl From<u64> for Max {
59 fn from(m: u64) -> Self {
60 Max::IntMax(m as usize)
61 }
62}
63
64impl From<isize> for Max {
65 fn from(m: isize) -> Self {
66 Max::IntMax(m as usize)
67 }
68}
69
70impl fmt::Display for Max {
71 fn fmt(&self, dest: &mut fmt::Formatter) -> fmt::Result {
72 match &self {
73 Max::Unbounded => write!(dest, "*"),
74 Max::IntMax(max) => write!(dest, "{max}"),
75 }
76 }
77}
78
79impl Serialize for Max {
80 fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
81 where
82 S: Serializer,
83 {
84 let value: i64 = match *self {
85 Max::Unbounded => -1,
86 Max::IntMax(n) => n as i64,
87 };
88 serializer.serialize_i64(value)
89 }
90}
91
92struct MaxVisitor;
93
94impl Visitor<'_> for MaxVisitor {
95 type Value = Max;
96
97 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
98 formatter.write_str("a positive integer or -1")
99 }
100
101 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
102 where
103 E: de::Error,
104 {
105 if value < -1 {
106 Err(E::custom(format!(
107 "value of type i64 {} should be -1 or positive",
108 value
109 )))
110 } else {
111 match value {
112 -1 => Ok(Max::Unbounded),
113 n => Ok(Max::from(n)),
114 }
115 }
116 }
117
118 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
119 where
120 E: de::Error,
121 {
122 Ok(Max::from(value))
123 }
124}
125
126impl<'de> Deserialize<'de> for Max {
127 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
128 where
129 D: Deserializer<'de>,
130 {
131 deserializer.deserialize_i64(MaxVisitor)
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use crate::Min;
141
142 #[test]
143 fn test_serialize_min() {
144 let min = Min::from(23);
145 let str = serde_json::to_string(&min).unwrap();
146 assert_eq!(str, "23");
147 }
148
149 #[test]
150 fn test_deserialize_min() {
151 let min = Min::from(23);
152 let min_deser = serde_json::from_str("23").unwrap();
153 assert_eq!(min, min_deser);
154 }
155}