1use crate::OneOrMany;
2
3impl<T: ToOwned<Owned = T>> FromIterator<T> for OneOrMany<T> {
4 #[inline]
5 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
6 let mut result: Self = Self::None;
7 result.extend(iter);
8 result
9 }
10}
11
12#[allow(clippy::module_name_repetitions)]
13pub struct Iter<'a, T> {
14 inner: &'a OneOrMany<T>,
15 index: usize,
16}
17
18impl<T> OneOrMany<T> {
19 #[inline]
21 #[must_use]
22 pub const fn iter(&self) -> Iter<'_, T> {
23 Iter {
24 inner: self,
25 index: 0,
26 }
27 }
28}
29
30impl<'a, T> IntoIterator for &'a OneOrMany<T> {
31 type IntoIter = Iter<'a, T>;
32 type Item = &'a T;
33
34 #[inline]
35 fn into_iter(self) -> Self::IntoIter {
36 self.iter()
37 }
38}
39
40impl<'a, T> Iterator for Iter<'a, T> {
41 type Item = &'a T;
42
43 #[inline]
44 fn next(&mut self) -> Option<Self::Item> {
45 let result = self.inner.get(self.index);
46 self.index += 1;
47 result
48 }
49}
50
51#[allow(clippy::module_name_repetitions)]
57pub struct IntoIter<T> {
58 inner_iter: InnerIntoIter<T>,
59}
60
61enum InnerIntoIter<T> {
62 One(Option<T>),
63 Many(std::vec::IntoIter<T>),
64 None,
65}
66
67impl<T> IntoIterator for OneOrMany<T> {
68 type IntoIter = IntoIter<T>;
69 type Item = T;
70
71 #[inline]
72 fn into_iter(self) -> Self::IntoIter {
73 let inner_iter = match self {
74 Self::One(t) => InnerIntoIter::One(Some(*t)),
75 Self::Many(v) => InnerIntoIter::Many(v.into_iter()),
76 Self::None => InnerIntoIter::None,
77 };
78
79 IntoIter { inner_iter }
80 }
81}
82
83impl<T> Iterator for IntoIter<T> {
84 type Item = T;
85
86 #[inline]
87 fn next(&mut self) -> Option<Self::Item> {
88 match self.inner_iter {
89 InnerIntoIter::One(ref mut t) => t.take(),
90 InnerIntoIter::Many(ref mut v) => v.next(),
91 InnerIntoIter::None => None,
92 }
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use crate::OneOrMany;
99 use pretty_assertions::assert_eq;
100 use rstest::rstest;
101
102 #[rstest]
103 #[case::none(Vec::<usize>::new().into_iter(), OneOrMany::<usize>::None)]
104 #[case::one(vec![1].into_iter(), OneOrMany::from(1))]
105 #[case::many(vec![1,2,3].into_iter(), OneOrMany::Many(vec![1,2,3]))]
106 fn test_from_iter<T, I>(#[case] input: I, #[case] expected: OneOrMany<T>)
107 where
108 T: std::fmt::Debug + Clone + std::cmp::PartialEq,
109 I: Iterator<Item = T>,
110 {
111 let collected = input.collect::<OneOrMany<_>>();
112 assert_eq!(collected, expected);
113 }
114
115 #[rstest]
116 #[case::none(OneOrMany::<usize>::None, vec![None])]
117 #[case::one(OneOrMany::from(1), vec![Some(1), None])]
118 #[case::many(OneOrMany::Many(vec![1, 2, 3]), vec![Some(1), Some(2), Some(3), None])]
119 fn test_iter<T>(#[case] input: OneOrMany<T>, #[case] expected: Vec<Option<T>>)
120 where
121 T: std::fmt::Debug + Clone + std::cmp::PartialEq,
122 {
123 let mut iter = input.iter();
124
125 for item in expected {
126 let next = iter.next();
127 assert_eq!(next, item.as_ref());
128 }
129 }
130
131 #[rstest]
132 #[case::none(OneOrMany::<usize>::None, vec![None])]
133 #[case::one(OneOrMany::from(1), vec![Some(1), None])]
134 #[case::many(OneOrMany::Many(vec![1, 2, 3]), vec![Some(1), Some(2), Some(3), None])]
135 fn test_into_iter_byval<T>(#[case] input: OneOrMany<T>, #[case] expected: Vec<Option<T>>)
136 where
137 T: std::fmt::Debug + Clone + std::cmp::PartialEq,
138 {
139 let mut iter = input.into_iter();
140
141 for item in expected {
142 let next = iter.next();
143 assert_eq!(next, item);
144 }
145 }
146
147 #[rstest]
148 #[case::none(OneOrMany::<usize>::None)]
149 #[case::one(OneOrMany::from(1))]
150 #[case::many(OneOrMany::Many(vec![1, 2, 3]))]
151 fn test_for_loop<T>(#[case] input: OneOrMany<T>)
152 where
153 T: std::fmt::Debug + Clone + std::cmp::PartialEq,
154 {
155 let mut iter = input.iter();
157 for item in &input {
158 assert_eq!(iter.next(), Some(item));
159 }
160 assert_eq!(iter.next(), None);
161
162 let mut iter = input.clone().into_iter();
164 for item in input {
165 assert_eq!(iter.next(), Some(item));
166 }
167 assert_eq!(iter.next(), None);
168 }
169}