rbe/
max.rs

1use serde::de;
2use serde::de::Visitor;
3use serde::Deserialize;
4use serde::Deserializer;
5use serde::Serialize;
6use serde::Serializer;
7use std::fmt;
8
9/// Represents a max cardinality which can be a fixed integer or `Unbounded`
10#[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 serde_json::*;
138    // use serde::Serialize;
139
140    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}