maybe_multiple/
maybe_multiple.rs1use crate::Multiple;
4
5#[derive(Debug, PartialEq, Eq)]
6#[cfg_attr(
7 feature = "serde",
8 derive(serde::Serialize, serde::Deserialize),
9 serde(untagged)
10)]
11pub enum MaybeMultiple<T> {
12 None,
13 Some(T),
14 Multiple(Multiple<T>),
15}
16
17impl<T> MaybeMultiple<T> {
22 #[must_use = "to assert that this doesn't have a value, wrap this in an `assert!()` instead"]
23 #[inline]
24 pub fn is_none(&self) -> bool {
25 matches!(self, Self::None)
26 }
27
28 #[must_use = "to assert that this has a value, wrap this in an `assert!()` instead"]
29 #[inline]
30 pub fn is_some(&self) -> bool {
31 matches!(self, Self::Some(_))
32 }
33
34 #[must_use = "to assert that this has a value, wrap this in an `assert!()` instead"]
35 #[inline]
36 pub fn is_multiple(&self) -> bool {
37 matches!(self, Self::Multiple(_))
38 }
39
40 #[inline]
41 pub fn from_vec(v: Vec<T>) -> Self {
42 Self::from(v)
43 }
44}
45
46impl<T> Default for MaybeMultiple<T> {
51 fn default() -> Self {
52 Self::None
53 }
54}
55
56impl<T> From<T> for MaybeMultiple<T> {
57 fn from(t: T) -> Self {
58 Self::Some(t)
59 }
60}
61
62impl<T> From<Vec<T>> for MaybeMultiple<T> {
63 fn from(mut v: Vec<T>) -> Self {
64 match v.len() {
65 0 => Self::None,
66 1 => Self::Some(v.pop().expect("input vec has one element")),
67 _ => Self::Multiple(v.try_into().expect("input vec has more than one element")),
68 }
69 }
70}
71
72impl<T> From<MaybeMultiple<T>> for Vec<T> {
73 fn from(maybe_multiple: MaybeMultiple<T>) -> Self {
74 match maybe_multiple {
75 MaybeMultiple::None => vec![],
76 MaybeMultiple::Some(v) => vec![v],
77 MaybeMultiple::Multiple(m) => m.into(),
78 }
79 }
80}
81
82#[cfg(test)]
87mod tests {
88 use super::MaybeMultiple;
89 use pretty_assertions::assert_eq;
90 use proptest::collection::size_range;
91 use test_strategy::proptest;
92
93 #[proptest]
94 fn proptest_conversions(v: Vec<u8>) {
95 match v.len() {
96 0 => assert_eq!(MaybeMultiple::from_vec(v), MaybeMultiple::None),
97 1 => {
98 let e = v[0];
99 assert_eq!(MaybeMultiple::from(v), MaybeMultiple::Some(e));
100 }
101 _ => assert_eq!(
102 MaybeMultiple::from(v.clone()),
103 MaybeMultiple::Multiple(v.try_into().unwrap())
104 ),
105 }
106 }
107
108 #[test]
109 fn serialize_deserialize_none() {
110 assert_eq!(
111 serde_json::to_string(&MaybeMultiple::<u8>::None).unwrap(),
112 "null"
113 );
114 assert_eq!(
115 serde_json::from_str::<MaybeMultiple<u8>>("null").unwrap(),
116 MaybeMultiple::None
117 );
118 }
119
120 #[proptest]
121 fn serialize_deserialize_some(val: u8) {
122 let maybe_multiple = MaybeMultiple::Some(val);
123 assert_eq!(
124 serde_json::to_string(&maybe_multiple).unwrap(),
125 serde_json::to_string(&val).unwrap()
126 );
127
128 let val_str = serde_json::to_string(&val).unwrap();
129 assert_eq!(
130 serde_json::from_str::<MaybeMultiple<_>>(&val_str).unwrap(),
131 maybe_multiple
132 );
133 }
134
135 #[proptest]
136 fn serialize_deserialize_multiple(#[any(size_range(2..128).lift())] vec: Vec<u8>) {
137 let maybe_multiple = MaybeMultiple::from_vec(vec.clone());
138 assert_eq!(
139 serde_json::to_string(&maybe_multiple).unwrap(),
140 serde_json::to_string(&vec).unwrap()
141 );
142
143 let vec_str = serde_json::to_string(&vec).unwrap();
144 assert_eq!(
145 serde_json::from_str::<MaybeMultiple<_>>(&vec_str).unwrap(),
146 maybe_multiple
147 );
148 }
149}