rbe/
min.rs

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