1#![deny(clippy::missing_inline_in_public_items)]
2
3mod iter;
4pub use iter::Iter;
5#[cfg(feature = "surrealdb")]
6mod query_result_impl;
7
8use std::{
9 clone::Clone,
10 ops::{Index, IndexMut},
11 slice::SliceIndex,
12};
13
14#[cfg(feature = "serde")]
15use serde::{Deserialize, Serialize};
16
17#[derive(Debug, PartialEq, Eq, Default)]
23#[cfg_attr(feature = "serde", derive(Serialize))]
24#[cfg_attr(feature = "serde", serde(untagged))]
25pub enum OneOrMany<T> {
26 One(Box<T>),
27 Many(Vec<T>),
28 #[default]
29 None,
30}
31
32#[cfg(feature = "serde")]
33impl<'de, T> Deserialize<'de> for OneOrMany<T>
34where
35 T: Deserialize<'de> + Clone,
36{
37 #[inline]
38 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
39 where
40 D: serde::Deserializer<'de>,
41 {
42 #[derive(Deserialize)]
43 #[serde(untagged)]
44 enum Inner<T> {
45 One(Box<T>),
46 Many(Vec<T>),
47 None,
48 }
49
50 let inner = Inner::deserialize(deserializer)?;
51 Ok(match inner {
52 Inner::One(t) => Self::One(t),
53 Inner::Many(t) if t.is_empty() => Self::None,
54 Inner::Many(t) if t.len() == 1 => Self::One(Box::new(t[0].clone())),
55 Inner::Many(t) => Self::Many(t),
56 Inner::None => Self::None,
57 })
58 }
59}
60
61impl<T> OneOrMany<T> {
62 #[inline]
64 #[must_use]
65 pub const fn len(&self) -> usize {
66 match self {
67 Self::One(_) => 1,
68 Self::Many(t) => t.len(),
69 Self::None => 0,
70 }
71 }
72
73 #[inline]
75 #[must_use]
76 pub const fn is_empty(&self) -> bool {
77 self.len() == 0
78 }
79
80 #[inline]
82 #[must_use]
83 pub fn get(&self, index: usize) -> Option<&T> {
84 match self {
85 Self::One(t) if index == 0 => Some(t),
86 Self::One(_) | Self::None => None,
87 Self::Many(t) => t.get(index),
88 }
89 }
90
91 #[inline]
93 #[must_use]
94 pub const fn first(&self) -> Option<&T> {
95 match self {
96 Self::One(t) => Some(t),
97 Self::Many(v) => v.as_slice().first(),
98 Self::None => None,
99 }
100 }
101
102 #[inline]
104 pub fn contains(&self, genre: &T) -> bool
105 where
106 T: PartialEq,
107 {
108 match self {
109 Self::One(t) => t.as_ref() == genre,
110 Self::Many(t) => t.contains(genre),
111 Self::None => false,
112 }
113 }
114
115 #[inline]
117 pub fn push(&mut self, new: T)
118 where
119 T: ToOwned<Owned = T>,
120 {
121 match self {
122 Self::One(t) => {
123 *self = Self::Many(vec![t.to_owned(), new]);
124 }
125 Self::Many(t) => t.push(new),
126 Self::None => *self = Self::One(Box::new(new)),
127 }
128 }
129
130 #[inline]
132 pub fn pop(&mut self) -> Option<T>
133 where
134 T: ToOwned<Owned = T>,
135 {
136 match self {
137 Self::One(t) => {
138 let old = t.to_owned();
139 *self = Self::None;
140 Some(old)
141 }
142 Self::Many(t) => {
143 let old = t.pop();
144 if t.len() == 1 {
145 *self = Self::One(Box::new(t[0].to_owned()));
146 }
147 old
148 }
149 Self::None => None,
150 }
151 }
152
153 #[inline]
155 #[must_use]
156 pub const fn is_none(&self) -> bool {
157 matches!(self, Self::None)
158 }
159
160 #[inline]
162 #[must_use]
163 pub const fn is_one(&self) -> bool {
164 matches!(self, Self::One(_))
165 }
166
167 #[inline]
169 #[must_use]
170 pub const fn is_many(&self) -> bool {
171 matches!(self, Self::Many(_))
172 }
173
174 #[inline]
176 #[must_use]
177 pub const fn is_some(&self) -> bool {
178 self.is_one() || self.is_many()
179 }
180
181 #[inline]
183 #[must_use]
184 pub const fn as_slice(&self) -> &[T] {
185 match self {
186 Self::One(t) => std::slice::from_ref(t),
187 Self::Many(t) => t.as_slice(),
188 Self::None => &[],
189 }
190 }
191
192 #[inline]
194 pub fn as_mut_slice(&mut self) -> &mut [T] {
195 match self {
196 Self::One(t) => std::slice::from_mut(t),
197 Self::Many(t) => t.as_mut_slice(),
198 Self::None => &mut [],
199 }
200 }
201
202 #[inline]
206 pub fn dedup(&mut self)
207 where
208 T: Clone + Eq + std::hash::Hash,
209 {
210 let mut set = std::collections::HashSet::new();
211 let mut new = Vec::new();
212 for t in self.as_slice() {
213 if set.insert(t) {
214 new.push(t.clone());
215 }
216 }
217 *self = Self::from(new);
218 }
219
220 #[inline]
224 pub fn dedup_by_key<F, K>(&mut self, mut key: F)
225 where
226 F: FnMut(&T) -> K,
227 K: Eq + std::hash::Hash,
228 T: Clone,
229 {
230 let mut set = std::collections::HashSet::new();
231 let mut new = Vec::new();
232 for t in self.as_slice() {
233 let key = key(t);
234 if set.insert(key) {
235 new.push(t.to_owned());
236 }
237 }
238 *self = Self::from(new);
239 }
240}
241
242impl<T: Clone> Clone for OneOrMany<T> {
243 #[inline]
244 fn clone(&self) -> Self {
245 match self {
246 Self::One(t) => Self::One(t.clone()),
247 Self::Many(t) => Self::Many(t.clone()),
248 Self::None => Self::None,
249 }
250 }
251}
252
253impl<T> From<T> for OneOrMany<T> {
254 #[inline]
255 fn from(t: T) -> Self {
256 Self::One(Box::new(t))
257 }
258}
259
260impl<T> From<Box<T>> for OneOrMany<T> {
261 #[inline]
262 fn from(t: Box<T>) -> Self {
263 Self::One(t)
264 }
265}
266
267impl<T> From<Option<T>> for OneOrMany<T> {
268 #[inline]
269 fn from(t: Option<T>) -> Self {
270 t.map(Box::new).map_or(Self::None, Self::One)
271 }
272}
273impl<T> From<Option<Box<T>>> for OneOrMany<T> {
274 #[inline]
275 fn from(t: Option<Box<T>>) -> Self {
276 t.map_or(Self::None, Self::One)
277 }
278}
279
280impl<T> From<Option<Vec<T>>> for OneOrMany<T> {
281 #[inline]
282 fn from(t: Option<Vec<T>>) -> Self {
283 t.map_or(Self::None, Into::into)
284 }
285}
286
287impl<T> From<Option<Self>> for OneOrMany<T> {
288 #[inline]
289 fn from(t: Option<Self>) -> Self {
290 t.unwrap_or(Self::None)
291 }
292}
293
294impl<T: Clone> From<&[T]> for OneOrMany<T> {
295 #[inline]
296 fn from(t: &[T]) -> Self {
297 if t.is_empty() {
298 Self::None
299 } else if t.len() == 1 {
300 Self::One(Box::new(t[0].clone()))
301 } else {
302 Self::Many(t.into())
303 }
304 }
305}
306
307impl<T> From<Vec<T>> for OneOrMany<T> {
308 #[inline]
309 fn from(t: Vec<T>) -> Self {
310 if t.len() <= 1 {
311 t.into_iter()
312 .next()
313 .map(Box::new)
314 .map_or(Self::None, Self::One)
315 } else {
316 Self::Many(t)
317 }
318 }
319}
320
321impl<T> From<OneOrMany<T>> for Vec<T> {
322 #[inline]
323 fn from(value: OneOrMany<T>) -> Self {
324 match value {
325 OneOrMany::One(one) => vec![*one],
326 OneOrMany::Many(many) => many,
327 OneOrMany::None => vec![],
328 }
329 }
330}
331
332impl<T, I: SliceIndex<[T]>> Index<I> for OneOrMany<T> {
334 type Output = I::Output;
335
336 #[inline]
337 fn index(&self, index: I) -> &Self::Output {
338 Index::index(self.as_slice(), index)
339 }
340}
341impl<T, I: SliceIndex<[T]>> IndexMut<I> for OneOrMany<T> {
342 #[inline]
343 fn index_mut(&mut self, index: I) -> &mut Self::Output {
344 IndexMut::index_mut(self.as_mut_slice(), index)
345 }
346}
347
348impl<T> PartialOrd<Self> for OneOrMany<T>
351where
352 T: PartialOrd,
353{
354 #[inline]
355 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
356 match (self, other) {
357 (Self::One(t1), Self::One(t2)) => t1.partial_cmp(t2),
358 (Self::Many(t1), Self::Many(t2)) => t1.partial_cmp(t2),
359 (Self::None, Self::None) => Some(std::cmp::Ordering::Equal),
360 (Self::None, _) => Some(std::cmp::Ordering::Less),
361 (_, Self::None) => Some(std::cmp::Ordering::Greater),
362 (Self::One(_), _) => Some(std::cmp::Ordering::Less),
363 (_, Self::One(_)) => Some(std::cmp::Ordering::Greater),
364 }
365 }
366}
367
368impl<T> Ord for OneOrMany<T>
371where
372 T: Ord,
373{
374 #[inline]
375 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
376 match (self, other) {
377 (Self::One(t1), Self::One(t2)) => t1.cmp(t2),
378 (Self::Many(t1), Self::Many(t2)) => t1.cmp(t2),
379 (Self::None, Self::None) => std::cmp::Ordering::Equal,
380 (Self::None, _) => std::cmp::Ordering::Less,
381 (_, Self::None) => std::cmp::Ordering::Greater,
382 (Self::One(_), _) => std::cmp::Ordering::Less,
383 (_, Self::One(_)) => std::cmp::Ordering::Greater,
384 }
385 }
386}
387
388impl<T> Extend<T> for OneOrMany<T>
390where
391 T: ToOwned<Owned = T>,
392{
393 #[inline]
394 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
395 for item in iter {
396 self.push(item);
397 }
398 }
399}
400
401impl<T> std::hash::Hash for OneOrMany<T>
403where
404 T: std::hash::Hash,
405{
406 #[inline]
407 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
408 match self {
409 Self::One(t) => {
410 1u8.hash(state);
411 t.hash(state);
412 }
413 Self::Many(t) => {
414 2u8.hash(state);
415 t.hash(state);
416 }
417 Self::None => {
418 0u8.hash(state);
419 }
420 }
421 }
422}
423
424#[cfg(test)]
425mod tests {
426 use super::*;
427 use pretty_assertions::{assert_eq, assert_ne};
428 use rstest::rstest;
429
430 #[rstest]
431 #[case::none(OneOrMany::<usize>::None, "null")]
432 #[case::none(OneOrMany::<usize>::None, "[]")]
433 #[case::one(OneOrMany::from(1), "1")]
434 #[case::one(OneOrMany::from(1), "[1]")]
435 #[case::many(OneOrMany::Many(vec![1, 2, 3]), "[1, 2, 3]")]
436 fn test_deserialize(#[case] expected: OneOrMany<usize>, #[case] input: &str)
437 where
438 usize: serde::de::DeserializeOwned,
439 {
440 let actual: OneOrMany<usize> = serde_json::from_str(input).unwrap();
441 assert_eq!(actual, expected);
442 }
443
444 #[rstest]
445 #[case::none(OneOrMany::<usize>::None, 0)]
446 #[case::one(OneOrMany::from(1), 1)]
447 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 3)]
448 fn test_len<T>(#[case] input: OneOrMany<T>, #[case] expected: usize) {
449 let actual = input.len();
450 assert_eq!(actual, expected);
451 }
452
453 #[rstest]
454 #[case::none(OneOrMany::<usize>::None, true)]
455 #[case::one(OneOrMany::from(1), false)]
456 #[case::many(OneOrMany::Many(vec![1, 2, 3]), false)]
457 fn test_is_empty<T>(#[case] input: OneOrMany<T>, #[case] expected: bool) {
458 let actual = input.is_empty();
459 assert_eq!(actual, expected);
460 }
461
462 #[rstest]
463 #[case::none(OneOrMany::<usize>::None,0, None)]
464 #[case::none(OneOrMany::<usize>::None,1, None)]
465 #[case::one(OneOrMany::from(1), 0, Some(&1))]
466 #[case::one(OneOrMany::from(1), 1, None)]
467 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 0, Some(&1))]
468 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 1, Some(&2))]
469 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 2, Some(&3))]
470 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 3, None)]
471 fn test_get<T>(#[case] input: OneOrMany<T>, #[case] index: usize, #[case] expected: Option<&T>)
472 where
473 T: PartialEq + std::fmt::Debug,
474 {
475 let actual = input.get(index);
476 assert_eq!(actual, expected);
477 }
478
479 #[rstest]
480 #[case::none(OneOrMany::<usize>::None, None)]
481 #[case::one(OneOrMany::from(1), Some(&1))]
482 #[case::many(OneOrMany::Many(vec![1, 2, 3]), Some(&1))]
483 fn test_first<T>(#[case] input: OneOrMany<T>, #[case] expected: Option<&T>)
484 where
485 T: PartialEq + std::fmt::Debug,
486 {
487 let actual = input.first();
488 assert_eq!(actual, expected);
489 }
490
491 #[rstest]
492 #[case::none(OneOrMany::<usize>::None, 2, false)]
493 #[case::one(OneOrMany::from(1), 1, true)]
494 #[case::one(OneOrMany::from(1), 0, false)]
495 #[case::many(OneOrMany::Many(vec![1, 2, 3]),2, true)]
496 #[case::many(OneOrMany::Many(vec![1, 2, 3]),4, false)]
497 fn test_contains<T>(#[case] input: OneOrMany<T>, #[case] value: T, #[case] expected: bool)
498 where
499 T: PartialEq + std::fmt::Debug,
500 {
501 let actual = input.contains(&value);
502 assert_eq!(actual, expected);
503 }
504
505 #[rstest]
506 #[case::none(OneOrMany::<usize>::None, 1, OneOrMany::from(1))]
507 #[case::one(OneOrMany::from(1), 2, OneOrMany::Many(vec![1, 2]))]
508 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 4, OneOrMany::Many(vec![1, 2, 3, 4]))]
509 fn test_push<T>(#[case] mut input: OneOrMany<T>, #[case] new: T, #[case] expected: OneOrMany<T>)
510 where
511 T: Clone + PartialEq + std::fmt::Debug,
512 {
513 input.push(new);
514 assert_eq!(input, expected);
515 }
516
517 #[rstest]
518 #[case::none(OneOrMany::<usize>::None, None, OneOrMany::<usize>::None)]
519 #[case::one(OneOrMany::from(1), Some(1), OneOrMany::<usize>::None)]
520 #[case::many(OneOrMany::Many(vec![1, 2]), Some(2), OneOrMany::from(1))]
521 #[case::many(OneOrMany::Many(vec![1, 2, 3]), Some(3), OneOrMany::Many(vec![1, 2]))]
522 fn test_pop<T>(
523 #[case] mut input: OneOrMany<T>,
524 #[case] expected: Option<T>,
525 #[case] expected_output: OneOrMany<T>,
526 ) where
527 T: Clone + PartialEq + std::fmt::Debug,
528 {
529 let result = input.pop();
530 assert_eq!(result, expected);
531 assert_eq!(input, expected_output);
532 }
533
534 #[rstest]
535 #[case::none(OneOrMany::<usize>::None, true)]
536 #[case::one(OneOrMany::from(1), false)]
537 #[case::many(OneOrMany::Many(vec![1, 2, 3]), false)]
538 fn test_is_none<T>(#[case] input: OneOrMany<T>, #[case] expected: bool)
539 where
540 T: PartialEq + std::fmt::Debug,
541 {
542 let actual = input.is_none();
543 assert_eq!(actual, expected);
544 }
545
546 #[rstest]
547 #[case::none(OneOrMany::<usize>::None, false)]
548 #[case::one(OneOrMany::from(1), true)]
549 #[case::many(OneOrMany::Many(vec![1, 2, 3]), false)]
550 fn test_is_one<T>(#[case] input: OneOrMany<T>, #[case] expected: bool)
551 where
552 T: PartialEq + std::fmt::Debug,
553 {
554 let actual = input.is_one();
555 assert_eq!(actual, expected);
556 }
557
558 #[rstest]
559 #[case::none(OneOrMany::<usize>::None, false)]
560 #[case::one(OneOrMany::from(1), false)]
561 #[case::many(OneOrMany::Many(vec![1, 2, 3]), true)]
562 fn test_is_many<T>(#[case] input: OneOrMany<T>, #[case] expected: bool)
563 where
564 T: PartialEq + std::fmt::Debug,
565 {
566 let actual = input.is_many();
567 assert_eq!(actual, expected);
568 }
569
570 #[rstest]
571 #[case::none(OneOrMany::<usize>::None, false)]
572 #[case::one(OneOrMany::from(1), true)]
573 #[case::many(OneOrMany::Many(vec![1, 2, 3]), true)]
574 fn test_is_some<T>(#[case] input: OneOrMany<T>, #[case] expected: bool)
575 where
576 T: PartialEq + std::fmt::Debug,
577 {
578 let actual = input.is_some();
579 assert_eq!(actual, expected);
580 }
581
582 #[rstest]
583 #[case::none(OneOrMany::<usize>::None, vec![])]
584 #[case::one(OneOrMany::from(1), vec![1])]
585 #[case::many(OneOrMany::Many(vec![1, 2, 3]), vec![1, 2, 3])]
586 fn test_as_slice<T>(#[case] input: OneOrMany<T>, #[case] expected: Vec<T>)
587 where
588 T: PartialEq + std::fmt::Debug,
589 {
590 assert_eq!(input.as_slice(), expected.as_slice());
591 }
592
593 #[rstest]
594 #[case::none(OneOrMany::<usize>::None, vec![])]
595 #[case::one(OneOrMany::from(1), vec![1])]
596 #[case::many(OneOrMany::Many(vec![1, 2, 3]), vec![1, 2, 3])]
597 fn test_as_mut_slice<T>(#[case] mut input: OneOrMany<T>, #[case] mut expected: Vec<T>)
598 where
599 T: PartialEq + std::fmt::Debug,
600 {
601 assert_eq!(input.as_mut_slice(), expected.as_mut_slice());
602 }
603
604 #[rstest]
605 #[case::one(1, OneOrMany::from(1))]
606 fn test_from<T>(#[case] input: T, #[case] expected: OneOrMany<T>)
607 where
608 T: Clone + PartialEq + std::fmt::Debug,
609 {
610 let actual = OneOrMany::from(input);
611 assert_eq!(actual, expected);
612 }
613
614 #[rstest]
615 #[case::none(vec![], OneOrMany::<usize>::None)]
616 #[case::one(vec![1], OneOrMany::from(1))]
617 #[case::many(vec![1, 2, 3], OneOrMany::Many(vec![1, 2, 3]))]
618 fn test_from_vec<T>(#[case] input: Vec<T>, #[case] expected: OneOrMany<T>)
619 where
620 T: PartialEq + std::fmt::Debug,
621 {
622 let actual = OneOrMany::from(input);
623 assert_eq!(actual, expected);
624 }
625
626 #[rstest]
627 #[case::none(&[], OneOrMany::<usize>::None)]
628 #[case::one(&[1], OneOrMany::from(1))]
629 #[case::many(&[1, 2, 3], OneOrMany::Many(vec![1, 2, 3]))]
630 fn test_from_slice<T>(#[case] input: &[T], #[case] expected: OneOrMany<T>)
631 where
632 T: PartialEq + std::fmt::Debug + Clone,
633 {
634 let actual = OneOrMany::from(input);
635 assert_eq!(actual, expected);
636 }
637
638 #[rstest]
639 #[case::none(None, OneOrMany::<usize>::None)]
640 #[case::one(Some(1), OneOrMany::from(1))]
641 fn test_from_option(#[case] input: Option<usize>, #[case] expected: OneOrMany<usize>) {
642 let actual = OneOrMany::from(input);
643 assert_eq!(actual, expected);
644 }
645
646 #[rstest]
647 #[case::none(None, OneOrMany::<usize>::None)]
648 #[case::one(Some(OneOrMany::from(1)), OneOrMany::from(1))]
649 #[case::many(Some(OneOrMany::Many(vec![1, 2, 3])), OneOrMany::Many(vec![1, 2, 3]))]
650 fn test_from_option_self(
651 #[case] input: Option<OneOrMany<usize>>,
652 #[case] expected: OneOrMany<usize>,
653 ) {
654 let actual = OneOrMany::from(input);
655 assert_eq!(actual, expected);
656 }
657
658 #[rstest]
659 #[case::none(Option::<Vec<usize>>::None, OneOrMany::None)]
660 #[case::one(Some(vec![1]), OneOrMany::from(1))]
661 #[case::many(Some(vec![1, 2, 3]), OneOrMany::Many(vec![1, 2, 3]))]
662 fn test_from_option_vec(#[case] input: Option<Vec<usize>>, #[case] expected: OneOrMany<usize>) {
663 let actual = OneOrMany::from(input);
664 assert_eq!(actual, expected);
665 }
666
667 #[rstest]
668 #[case::none(OneOrMany::<usize>::None, vec![])]
669 #[case::one(OneOrMany::from(1), vec![1])]
670 #[case::many(OneOrMany::Many(vec![1, 2, 3]), vec![1, 2, 3])]
671 fn test_into_vec(#[case] input: OneOrMany<usize>, #[case] expected: Vec<usize>) {
672 let actual = Vec::from(input);
673 assert_eq!(actual, expected);
674 }
675
676 #[rstest]
677 #[should_panic = "index out of bounds: the len is 0 but the index is 0"]
678 #[case::none(OneOrMany::<usize>::None, 0, 0)]
679 #[case::one(OneOrMany::from(1), 0, 1)]
680 #[should_panic = "index out of bounds: the len is 1 but the index is 1"]
681 #[case::one(OneOrMany::from(1), 1, 0)]
682 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 0, 1)]
683 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 1, 2)]
684 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 2, 3)]
685 #[should_panic = "index out of bounds: the len is 3 but the index is 3"]
686 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 3, 4)]
687 fn test_index<T>(#[case] input: OneOrMany<T>, #[case] index: usize, #[case] expected: T)
688 where
689 T: PartialEq + std::fmt::Debug + Copy,
690 {
691 let actual = input[index];
692 assert_eq!(actual, expected);
693 }
694
695 #[rstest]
696 #[case::none(OneOrMany::<usize>::None, 0..0, &[])]
697 #[should_panic = "range end index 1 out of range for slice of length 0"]
698 #[case::none(OneOrMany::<usize>::None, 0..1, &[])]
699 #[case::one(OneOrMany::from(1), 0..0, &[])]
700 #[case::one(OneOrMany::from(1), 0..1, &[1])]
701 #[should_panic = "range end index 2 out of range for slice of length 1"]
702 #[case::one(OneOrMany::from(1), 1..2, &[])]
703 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 0..0, &[])]
704 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 0..1, &[1])]
705 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 1..2, &[2])]
706 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 2..3, &[3])]
707 #[should_panic = "range end index 4 out of range for slice of length 3"]
708 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 3..4, &[])]
709 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 0..3, &[1, 2, 3])]
710 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 0..2, &[1, 2])]
711 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 1..3, &[2, 3])]
712 fn test_index_slice<'a, T, I>(
713 #[case] input: OneOrMany<T>,
714 #[case] index: I,
715 #[case] expected: &[T],
716 ) where
717 T: PartialEq + std::fmt::Debug,
718 I: std::slice::SliceIndex<[T], Output = [T]>,
719 {
720 let actual = &input[index];
721 assert_eq!(actual, expected);
722 }
723
724 #[rstest]
725 #[case::none(OneOrMany::<usize>::None, 0..0, &[])]
726 #[should_panic = "range end index 1 out of range for slice of length 0"]
727 #[case::none(OneOrMany::<usize>::None, 0..1, &[])]
728 #[case::one(OneOrMany::from(1), 0..0, &[])]
729 #[case::one(OneOrMany::from(1), 0..1, &[1])]
730 #[should_panic = "range end index 2 out of range for slice of length 1"]
731 #[case::one(OneOrMany::from(1), 1..2, &[])]
732 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 0..0, &[])]
733 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 0..1, &[1])]
734 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 1..2, &[2])]
735 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 2..3, &[3])]
736 #[should_panic = "range end index 4 out of range for slice of length 3"]
737 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 3..4, &[])]
738 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 0..3, &[1, 2, 3])]
739 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 0..2, &[1, 2])]
740 #[case::many(OneOrMany::Many(vec![1, 2, 3]), 1..3, &[2, 3])]
741 fn test_index_mut_slice<'a, T, I>(
742 #[case] mut input: OneOrMany<T>,
743 #[case] index: I,
744 #[case] expected: &[T],
745 ) where
746 T: PartialEq + std::fmt::Debug,
747 I: std::slice::SliceIndex<[T], Output = [T]>,
748 {
749 let actual = &mut input[index];
750 assert_eq!(actual, expected);
751 }
752
753 #[rstest]
754 #[case::none(OneOrMany::<usize>::None, OneOrMany::<usize>::None, Some(std::cmp::Ordering::Equal))]
755 #[case::none(OneOrMany::<usize>::None, OneOrMany::from(1), Some(std::cmp::Ordering::Less))]
756 #[case::none(OneOrMany::<usize>::None, OneOrMany::Many(vec![1, 2, 3]), Some(std::cmp::Ordering::Less))]
757 #[case::one(OneOrMany::from(1), OneOrMany::<usize>::None, Some(std::cmp::Ordering::Greater))]
758 #[case::one(
759 OneOrMany::from(1),
760 OneOrMany::from(1),
761 Some(std::cmp::Ordering::Equal)
762 )]
763 #[case::one(OneOrMany::from(1), OneOrMany::from(2), Some(std::cmp::Ordering::Less))]
764 #[case::one(
765 OneOrMany::from(1),
766 OneOrMany::from(0),
767 Some(std::cmp::Ordering::Greater)
768 )]
769 #[case::one(OneOrMany::from(1), OneOrMany::Many(vec![1, 2, 3]), Some(std::cmp::Ordering::Less))]
770 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::<usize>::None, Some(std::cmp::Ordering::Greater))]
771 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::from(1), Some(std::cmp::Ordering::Greater))]
772 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::Many(vec![1, 2, 3]), Some(std::cmp::Ordering::Equal))]
773 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::Many(vec![2, 3]), Some(std::cmp::Ordering::Less))]
774 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::Many(vec![1, 2, 3, 4]), Some(std::cmp::Ordering::Less))]
775 fn test_partial_cmp<T>(
776 #[case] input: OneOrMany<T>,
777 #[case] other: OneOrMany<T>,
778 #[case] expected: Option<std::cmp::Ordering>,
779 ) where
780 T: std::fmt::Debug + PartialOrd,
781 {
782 let actual = input.partial_cmp(&other);
783 assert_eq!(actual, expected);
784 }
785
786 #[rstest]
787 #[case::none(OneOrMany::<usize>::None, OneOrMany::<usize>::None, std::cmp::Ordering::Equal)]
788 #[case::none(OneOrMany::<usize>::None, OneOrMany::from(1), std::cmp::Ordering::Less)]
789 #[case::none(OneOrMany::<usize>::None, OneOrMany::Many(vec![1, 2, 3]), std::cmp::Ordering::Less)]
790 #[case::one(OneOrMany::from(1), OneOrMany::<usize>::None, std::cmp::Ordering::Greater)]
791 #[case::one(OneOrMany::from(1), OneOrMany::from(1), std::cmp::Ordering::Equal)]
792 #[case::one(OneOrMany::from(1), OneOrMany::from(2), std::cmp::Ordering::Less)]
793 #[case::one(OneOrMany::from(1), OneOrMany::from(0), std::cmp::Ordering::Greater)]
794 #[case::one(OneOrMany::from(1), OneOrMany::Many(vec![1, 2, 3]), std::cmp::Ordering::Less)]
795 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::<usize>::None, std::cmp::Ordering::Greater)]
796 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::from(1), std::cmp::Ordering::Greater)]
797 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::Many(vec![1, 2, 3]), std::cmp::Ordering::Equal)]
798 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::Many(vec![2, 3]), std::cmp::Ordering::Less)]
799 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::Many(vec![1, 2, 3, 4]), std::cmp::Ordering::Less)]
800 fn test_cmp<T>(
801 #[case] input: OneOrMany<T>,
802 #[case] other: OneOrMany<T>,
803 #[case] expected: std::cmp::Ordering,
804 ) where
805 T: std::fmt::Debug + Ord,
806 {
807 let actual = input.cmp(&other);
808 assert_eq!(actual, expected);
809 }
810
811 #[rstest]
812 #[case::none(OneOrMany::<usize>::None, OneOrMany::<usize>::None)]
813 #[case::one(OneOrMany::from(1), OneOrMany::from(1))]
814 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::Many(vec![1, 2, 3]))]
815 fn test_eq<T>(#[case] input: OneOrMany<T>, #[case] other: OneOrMany<T>)
816 where
817 T: PartialEq + std::fmt::Debug,
818 {
819 assert_eq!(input, other);
820 }
821
822 #[rstest]
823 #[case::none(OneOrMany::<usize>::None, OneOrMany::from(1))]
824 #[case::one(OneOrMany::from(1), OneOrMany::Many(vec![1, 2, 3]))]
825 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::<usize>::None)]
826 fn test_ne<T>(#[case] input: OneOrMany<T>, #[case] other: OneOrMany<T>)
827 where
828 T: PartialEq + std::fmt::Debug,
829 {
830 assert_ne!(input, other);
831 }
832
833 #[rstest]
834 #[case::none(OneOrMany::<usize>::None, OneOrMany::<usize>::None)]
835 #[case::one(OneOrMany::from(1), OneOrMany::from(1))]
836 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::Many(vec![1, 2, 3]))]
837 #[case::many(OneOrMany::Many(vec![1, 1, 2, 3, 2]), OneOrMany::Many(vec![1, 2, 3]))]
838 #[case::many(OneOrMany::Many(vec![1, 1, 1]), OneOrMany::from(1))]
839 fn test_dedup<T>(#[case] mut input: OneOrMany<T>, #[case] expected: OneOrMany<T>)
840 where
841 T: Clone + Eq + std::hash::Hash + std::fmt::Debug,
842 {
843 input.dedup();
844 assert_eq!(input, expected);
845 }
846
847 #[rstest]
848 #[case::none(OneOrMany::<usize>::None, OneOrMany::<usize>::None)]
849 #[case::one(OneOrMany::from(1), OneOrMany::from(1))]
850 #[case::many(OneOrMany::Many(vec![1, 2, 3]), OneOrMany::Many(vec![1, 2, 3]))]
851 #[case::many(OneOrMany::Many(vec![1, 1, 2, 3, 2]), OneOrMany::Many(vec![1, 2, 3]))]
852 #[case::many(OneOrMany::Many(vec![1, 1, 1]), OneOrMany::from(1))]
853 fn test_dedup_by_key<T>(#[case] mut input: OneOrMany<T>, #[case] expected: OneOrMany<T>)
854 where
855 T: Clone + Eq + std::hash::Hash + std::fmt::Debug,
856 {
857 input.dedup_by_key(Clone::clone);
858 assert_eq!(input, expected);
859 }
860
861 #[rstest]
862 #[case::none_with_none(OneOrMany::<usize>::None, vec![], OneOrMany::<usize>::None)]
863 #[case::none_with_one(OneOrMany::<usize>::None, vec![1], OneOrMany::from(1))]
864 #[case::none_with_many(OneOrMany::<usize>::None, vec![1, 2, 3], OneOrMany::Many(vec![1, 2, 3]))]
865 #[case::none_with_many(OneOrMany::<usize>::None, vec![1, 1, 2, 3], OneOrMany::Many(vec![1, 1, 2, 3]))]
866 #[case::one_with_none(OneOrMany::from(1), vec![], OneOrMany::from(1))]
867 #[case::one_with_one(OneOrMany::from(1), vec![2], OneOrMany::Many(vec![1, 2]))]
868 #[case::one_with_one(OneOrMany::from(1), vec![1], OneOrMany::Many(vec![1, 1]))]
869 #[case::one_with_many(OneOrMany::from(1), vec![2, 3, 4], OneOrMany::Many(vec![1, 2, 3, 4]))]
870 #[case::one_with_many(OneOrMany::from(1), vec![1, 2, 3], OneOrMany::Many(vec![1, 1, 2, 3]))]
871 #[case::many_with_none(OneOrMany::Many(vec![1, 2, 3]), vec![], OneOrMany::Many(vec![1, 2, 3]))]
872 #[case::many_with_one(OneOrMany::Many(vec![1, 2, 3]), vec![4], OneOrMany::Many(vec![1, 2, 3, 4]))]
873 #[case::many_with_one(OneOrMany::Many(vec![1, 2, 3]), vec![1], OneOrMany::Many(vec![1, 2, 3, 1]))]
874 #[case::many_with_many(OneOrMany::Many(vec![1, 2, 3]), vec![4, 5, 6], OneOrMany::Many(vec![1, 2, 3, 4, 5, 6]))]
875 #[case::many_with_many(OneOrMany::Many(vec![1, 2, 3]), vec![3, 5, 6], OneOrMany::Many(vec![1, 2, 3, 3, 5, 6]))]
876 fn test_extend<T>(
877 #[case] mut base: OneOrMany<T>,
878 #[case] extend: impl IntoIterator<Item = T>,
879 #[case] expected: OneOrMany<T>,
880 ) where
881 T: Clone + PartialEq + std::fmt::Debug,
882 {
883 base.extend(extend);
884 assert_eq!(base, expected);
885 }
886}