rustrade_integration/collection/
one_or_many.rs1use crate::collection::none_one_or_many::NoneOneOrMany;
2use itertools::Either;
3use serde::{Deserialize, Serialize};
4use std::{
5 borrow::{Borrow, BorrowMut},
6 convert::AsRef,
7};
8
9#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Deserialize, Serialize)]
10pub enum OneOrMany<T> {
11 One(T),
12 Many(Vec<T>),
13}
14
15impl<T> OneOrMany<T> {
17 pub fn map<U, F>(self, f: F) -> OneOrMany<U>
18 where
19 F: Fn(T) -> U,
20 {
21 match self {
22 Self::One(x) => OneOrMany::One(f(x)),
23 Self::Many(vec) => OneOrMany::Many(vec.into_iter().map(f).collect()),
24 }
25 }
26
27 pub fn extend<Iter>(self, other: Iter) -> Self
28 where
29 Iter: IntoIterator<Item = T>,
30 {
31 let other = Self::from_iter(other);
32
33 use OneOrMany::*;
34 match (self, other) {
35 (One(left), One(right)) => Many(vec![left, right]),
36 (One(left), Many(mut right)) => {
37 right.push(left);
38 Many(right)
39 }
40 (Many(mut left), One(right)) => {
41 left.push(right);
42 Many(left)
43 }
44 (Many(mut left), Many(right)) => {
45 left.extend(right);
46 Many(left)
47 }
48 }
49 }
50
51 pub fn contains(&self, item: &T) -> bool
52 where
53 T: PartialEq,
54 {
55 match self {
56 Self::One(value) => value == item,
57 Self::Many(values) => values.contains(item),
58 }
59 }
60
61 #[allow(clippy::len_without_is_empty)]
62 pub fn len(&self) -> usize {
63 match self {
64 Self::One(_) => 1,
65 Self::Many(items) => items.len(),
66 }
67 }
68
69 pub fn is_one(&self) -> bool {
70 matches!(self, Self::One(_))
71 }
72
73 pub fn is_many(&self) -> bool {
74 matches!(self, Self::Many(_))
75 }
76
77 pub fn into_vec(self) -> Vec<T> {
78 match self {
79 Self::One(item) => vec![item],
80 Self::Many(items) => items,
81 }
82 }
83
84 pub fn iter(&self) -> std::slice::Iter<'_, T> {
85 self.as_ref().iter()
86 }
87}
88
89impl<T: Default> Default for OneOrMany<T> {
91 fn default() -> Self {
92 OneOrMany::One(T::default())
93 }
94}
95
96impl<T> AsRef<[T]> for OneOrMany<T> {
98 fn as_ref(&self) -> &[T] {
99 match self {
100 Self::One(item) => std::slice::from_ref(item),
101 Self::Many(items) => items.as_slice(),
102 }
103 }
104}
105
106impl<T> Borrow<[T]> for OneOrMany<T> {
108 fn borrow(&self) -> &[T] {
109 self.as_ref()
110 }
111}
112
113impl<T> BorrowMut<[T]> for OneOrMany<T> {
115 fn borrow_mut(&mut self) -> &mut [T] {
116 match self {
117 Self::One(item) => std::slice::from_mut(item),
118 Self::Many(items) => items.as_mut_slice(),
119 }
120 }
121}
122
123impl<T> From<T> for OneOrMany<T> {
125 fn from(item: T) -> Self {
126 OneOrMany::One(item)
127 }
128}
129
130impl<T> From<Vec<T>> for OneOrMany<T> {
131 fn from(mut items: Vec<T>) -> Self {
132 match items.len() {
133 0 => panic!("Cannot create OneOrMany from empty Vec"),
134 1 => OneOrMany::One(items.remove(0)),
135 _ => OneOrMany::Many(items),
136 }
137 }
138}
139
140impl<T> From<NoneOneOrMany<T>> for Option<OneOrMany<T>> {
141 fn from(value: NoneOneOrMany<T>) -> Self {
142 match value {
143 NoneOneOrMany::None => None,
144 NoneOneOrMany::One(value) => Some(OneOrMany::One(value)),
145 NoneOneOrMany::Many(values) => Some(OneOrMany::Many(values)),
146 }
147 }
148}
149
150impl<T> FromIterator<T> for OneOrMany<T> {
152 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
153 let mut collection = iter.into_iter().collect::<Vec<_>>();
154 match collection.len() {
155 1 => Self::One(collection.swap_remove(0)),
156 _ => Self::Many(collection),
157 }
158 }
159}
160
161impl<T> IntoIterator for OneOrMany<T> {
163 type Item = T;
164 type IntoIter = Either<std::iter::Once<T>, std::vec::IntoIter<T>>;
165
166 fn into_iter(self) -> Self::IntoIter {
167 match self {
168 OneOrMany::One(item) => Either::Left(std::iter::once(item)),
169 OneOrMany::Many(items) => Either::Right(items.into_iter()),
170 }
171 }
172}
173
174impl<'a, T> IntoIterator for &'a OneOrMany<T> {
176 type Item = &'a T;
177 type IntoIter = Either<std::iter::Once<&'a T>, std::slice::Iter<'a, T>>;
178
179 fn into_iter(self) -> Self::IntoIter {
180 match self {
181 OneOrMany::One(item) => Either::Left(std::iter::once(item)),
182 OneOrMany::Many(items) => Either::Right(items.iter()),
183 }
184 }
185}
186
187impl<'a, T> IntoIterator for &'a mut OneOrMany<T> {
189 type Item = &'a mut T;
190 type IntoIter = Either<std::iter::Once<&'a mut T>, std::slice::IterMut<'a, T>>;
191
192 fn into_iter(self) -> Self::IntoIter {
193 match self {
194 OneOrMany::One(item) => Either::Left(std::iter::once(item)),
195 OneOrMany::Many(items) => Either::Right(items.iter_mut()),
196 }
197 }
198}