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