1use std::fmt::{self, Display, Formatter};
6use std::{slice, vec};
7
8#[derive(Debug, Clone, Ord, PartialOrd, Eq)]
11pub enum OneOrMany<T> {
12 One(T),
14 Many(Vec<T>),
16}
17
18impl<T> OneOrMany<T> {
19 pub fn is_many(&self) -> bool {
21 match self {
22 Self::One(_) => false,
23 Self::Many(_) => true,
24 }
25 }
26
27 pub fn iter(&self) -> Iter<'_, T> {
29 match self {
30 Self::One(item) => Iter { inner_one: Some(item), inner_many: None },
31 Self::Many(items) => Iter { inner_one: None, inner_many: Some(items.iter()) },
32 }
33 }
34
35 pub fn len(&self) -> usize {
37 match self {
38 Self::One(_) => 1,
39 Self::Many(v) => v.len(),
40 }
41 }
42
43 pub fn as_ref<S>(&self) -> OneOrMany<&S>
45 where
46 T: AsRef<S>,
47 S: ?Sized,
48 {
49 match self {
50 Self::One(o) => OneOrMany::<&S>::One(o.as_ref()),
51 Self::Many(v) => OneOrMany::<&S>::Many(v.iter().map(|o| o.as_ref()).collect()),
52 }
53 }
54}
55
56impl<T> OneOrMany<T>
57where
58 T: Ord + Clone,
59{
60 pub fn canonicalize(&mut self) {
64 let mut replace_with = None;
65 match self {
66 OneOrMany::One(_) => {}
67 OneOrMany::Many(many) => {
68 if many.len() == 1 {
69 replace_with = Some(many.first().unwrap().clone());
70 } else {
71 many.sort();
72 }
73 }
74 }
75 if let Some(t) = replace_with {
76 *self = OneOrMany::One(t);
77 }
78 }
79}
80
81impl<T> OneOrMany<T>
82where
83 T: PartialEq,
84{
85 pub fn contains(&self, e: &T) -> bool {
87 match self {
88 Self::One(item) => item == e,
89 Self::Many(items) => items.contains(e),
90 }
91 }
92}
93
94impl<T> PartialEq for OneOrMany<T>
95where
96 T: PartialEq,
97{
98 fn eq(&self, other: &Self) -> bool {
99 self.iter().eq(other.into_iter())
100 }
101}
102
103impl<'a, T> IntoIterator for &'a OneOrMany<T> {
104 type Item = &'a T;
105 type IntoIter = Iter<'a, T>;
106
107 fn into_iter(self) -> Iter<'a, T> {
108 self.iter()
109 }
110}
111
112impl<T> IntoIterator for OneOrMany<T> {
113 type Item = T;
114 type IntoIter = IntoIter<T>;
115
116 fn into_iter(self) -> IntoIter<T> {
117 match self {
118 OneOrMany::One(item) => IntoIter { inner_one: Some(item), inner_many: None },
119 OneOrMany::Many(items) => {
120 IntoIter { inner_one: None, inner_many: Some(items.into_iter()) }
121 }
122 }
123 }
124}
125
126impl<T> FromIterator<T> for OneOrMany<T> {
127 fn from_iter<I>(iter: I) -> Self
128 where
129 I: IntoIterator<Item = T> + Sized,
130 {
131 let mut iter = iter.into_iter();
132 if let Some(first) = iter.next() {
133 let rest: Vec<_> = iter.collect();
134 if rest.is_empty() {
135 Self::One(first)
136 } else {
137 let mut out = vec![first];
138 out.extend(rest);
139 Self::Many(out)
140 }
141 } else {
142 Self::Many(vec![])
143 }
144 }
145}
146
147impl<T> From<T> for OneOrMany<T> {
148 fn from(item: T) -> Self {
149 Self::One(item)
150 }
151}
152
153impl<'a, T: Display> Display for OneOrMany<T> {
154 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
155 match self {
156 OneOrMany::One(item) => Display::fmt(item, f),
157 OneOrMany::Many(items) => {
158 let mut iter = items.iter();
159 if let Some(first_item) = iter.next() {
160 Display::fmt(first_item, f)?;
161 }
162 for item in iter {
163 f.write_str(", ")?;
164 Display::fmt(item, f)?;
165 }
166 Ok(())
167 }
168 }
169 }
170}
171
172pub struct Iter<'a, T> {
177 inner_one: Option<&'a T>,
178 inner_many: Option<slice::Iter<'a, T>>,
179}
180
181impl<'a, T> Iterator for Iter<'a, T> {
182 type Item = &'a T;
183
184 fn next(&mut self) -> Option<Self::Item> {
185 if let Some(item) = self.inner_one.take() {
186 Some(item)
187 } else if let Some(iter) = &mut self.inner_many {
188 iter.next()
189 } else {
190 None
191 }
192 }
193
194 fn size_hint(&self) -> (usize, Option<usize>) {
195 if let Some(_) = self.inner_one {
196 (1, Some(1))
197 } else if let Some(iter) = &self.inner_many {
198 iter.size_hint()
199 } else {
200 (0, Some(0))
201 }
202 }
203}
204
205impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
206
207pub struct IntoIter<T> {
213 inner_one: Option<T>,
214 inner_many: Option<vec::IntoIter<T>>,
215}
216
217impl<T> Iterator for IntoIter<T> {
218 type Item = T;
219
220 fn next(&mut self) -> Option<Self::Item> {
221 if let Some(item) = self.inner_one.take() {
222 Some(item)
223 } else if let Some(iter) = &mut self.inner_many {
224 iter.next()
225 } else {
226 None
227 }
228 }
229
230 fn size_hint(&self) -> (usize, Option<usize>) {
231 if let Some(_) = self.inner_one {
232 (1, Some(1))
233 } else if let Some(iter) = &self.inner_many {
234 iter.size_hint()
235 } else {
236 (0, Some(0))
237 }
238 }
239}
240
241impl<T> ExactSizeIterator for IntoIter<T> {}
242
243#[cfg(test)]
244mod tests {
245 use super::*;
246 use assert_matches::assert_matches;
247
248 #[test]
249 fn test_iter_one() {
250 let v = OneOrMany::One(34);
251 let mut iter = v.iter();
252 assert_matches!(iter.next(), Some(&34));
253 assert_matches!(iter.next(), None);
254 }
255
256 #[test]
257 fn test_iter_many() {
258 let v = OneOrMany::Many(vec![1, 2, 3]);
259 let mut iter = v.iter();
260 assert_matches!(iter.next(), Some(&1));
261 assert_matches!(iter.next(), Some(&2));
262 assert_matches!(iter.next(), Some(&3));
263 assert_matches!(iter.next(), None);
264 }
265
266 #[test]
267 fn test_is_many() {
268 let v = OneOrMany::One(34);
269 assert_eq!(v.is_many(), false);
270
271 let v = OneOrMany::Many(vec![1, 2, 3]);
272 assert_eq!(v.is_many(), true);
273 }
274
275 #[test]
276 fn test_from_iter() {
277 let o: OneOrMany<i64> = [34].into_iter().collect();
278 assert_eq!(o, OneOrMany::One(34));
279
280 let o: OneOrMany<i64> = [1, 2, 3].into_iter().collect();
281 assert_eq!(o, OneOrMany::Many(vec![1, 2, 3]));
282
283 let o: OneOrMany<i64> = [].into_iter().collect();
284 assert_eq!(o, OneOrMany::Many(vec![]));
285 }
286
287 #[test]
288 fn test_display() {
289 let val = 34;
290 let v = OneOrMany::One(val);
291 assert_eq!(v.to_string(), "34");
292
293 let val = vec![1, 2, 3];
294 let v = OneOrMany::Many(val);
295 assert_eq!(v.to_string(), "1, 2, 3");
296 }
297}