1use core::iter;
2
3#[allow(unused_imports)]
4use crate::AlternatingExt;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct AlternatingAll<I, J> {
11 i: I,
12 j: J,
13 next: Next,
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18enum Next {
19 I,
20 J,
21 IAlways,
23 JAlways,
25}
26
27impl<I, J> AlternatingAll<I, J>
28where
29 I: Iterator,
30 J: Iterator<Item = I::Item>,
31{
32 pub fn new(i: impl IntoIterator<IntoIter = I>, j: impl IntoIterator<IntoIter = J>) -> Self {
36 Self {
37 i: i.into_iter(),
38 j: j.into_iter(),
39 next: Next::I,
40 }
41 }
42}
43
44impl<I, J> Iterator for AlternatingAll<I, J>
45where
46 I: Iterator,
47 J: Iterator<Item = I::Item>,
48{
49 type Item = I::Item;
50
51 fn next(&mut self) -> Option<Self::Item> {
52 match self.next {
53 Next::I => {
54 if let Some(item) = self.i.next() {
55 self.next = Next::J;
56 Some(item)
57 } else {
58 self.next = Next::JAlways;
59 self.j.next()
60 }
61 }
62 Next::J => {
63 if let Some(item) = self.j.next() {
64 self.next = Next::I;
65 Some(item)
66 } else {
67 self.next = Next::IAlways;
68 self.i.next()
69 }
70 }
71 Next::IAlways => self.i.next(),
72 Next::JAlways => self.j.next(),
73 }
74 }
75
76 fn size_hint(&self) -> (usize, Option<usize>) {
77 let (i_lower, i_upper) = self.i.size_hint();
78 let (j_lower, j_upper) = self.j.size_hint();
79 (
80 usize::saturating_add(i_lower, j_lower),
81 i_upper.and_then(|i| j_upper.and_then(|j| usize::checked_add(i, j))),
82 )
83 }
84}
85
86impl<I, J> iter::FusedIterator for AlternatingAll<I, J>
100where
101 I: iter::FusedIterator,
102 J: iter::FusedIterator<Item = I::Item>,
103{
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[test]
111 fn equal_lengths() {
112 let a = [1, 2, 3];
113 let b = [4, 5, 6];
114
115 let mut iter = a.iter().alternate_with_all(b.iter());
116
117 assert_eq!(iter.next(), Some(&1));
118 assert_eq!(iter.next(), Some(&4));
119 assert_eq!(iter.next(), Some(&2));
120 assert_eq!(iter.next(), Some(&5));
121 assert_eq!(iter.next(), Some(&3));
122 assert_eq!(iter.next(), Some(&6));
123 assert_eq!(iter.next(), None);
124 }
125
126 #[test]
127 fn different_lengths() {
128 let a = [1, 2, 3];
129 let b = [4, 5];
130
131 let mut iter = a.iter().alternate_with_all(b.iter());
132
133 assert_eq!(iter.next(), Some(&1));
134 assert_eq!(iter.next(), Some(&4));
135 assert_eq!(iter.next(), Some(&2));
136 assert_eq!(iter.next(), Some(&5));
137 assert_eq!(iter.next(), Some(&3));
138 assert_eq!(iter.next(), None);
139 }
140
141 #[test]
142 fn empty_iterators() {
143 let a: [i32; 0] = [];
144 let b: [i32; 0] = [];
145
146 let mut iter = a.iter().alternate_with_all(b.iter());
147
148 assert_eq!(iter.next(), None);
149 }
150
151 #[test]
152 fn one_empty_iterator() {
153 let a = [1, 2, 3];
154 let b: [i32; 0] = [];
155
156 let mut iter = a.iter().alternate_with_all(b.iter());
157
158 assert_eq!(iter.next(), Some(&1));
159 assert_eq!(iter.next(), Some(&2));
160 assert_eq!(iter.next(), Some(&3));
161 assert_eq!(iter.next(), None);
162 }
163
164 #[test]
165 fn same_iterator() {
166 let a = [1, 2, 3];
167
168 let mut iter = a.iter().alternate_with_all(a.iter());
169
170 assert_eq!(iter.next(), Some(&1));
171 assert_eq!(iter.next(), Some(&1));
172 assert_eq!(iter.next(), Some(&2));
173 assert_eq!(iter.next(), Some(&2));
174 assert_eq!(iter.next(), Some(&3));
175 assert_eq!(iter.next(), Some(&3));
176 assert_eq!(iter.next(), None);
177 }
178 #[test]
179 fn size_hint_accurate() {
180 let a = [1, 2, 3];
181 let b = [4, 5];
182
183 assert_eq!(
184 a.iter().size_hint().1,
185 Some(a.iter().count()),
186 "Sanity check failed"
187 );
188 assert_eq!(
189 b.iter().size_hint().1,
190 Some(b.iter().count()),
191 "Sanity check failed"
192 );
193
194 let iter = a.iter().alternate_with_all(b.iter());
195
196 assert_eq!(iter.size_hint().1, Some(iter.count()));
197 }
198
199 #[test]
200 fn size_hint() {
201 let a = [1, 2, 3];
202 let b = [4, 5];
203
204 assert_eq!(a.iter().size_hint(), (3, Some(3)), "Sanity check failed");
205 assert_eq!(b.iter().size_hint(), (2, Some(2)), "Sanity check failed");
206
207 let iter = a.iter().alternate_with_all(b.iter());
208
209 assert_eq!(iter.size_hint(), (5, Some(5)));
210 assert_eq!(iter.count(), 5, "Inaccurate size hint");
211 }
212 #[test]
213 fn size_hint_unbounded_right() {
214 let a = [1, 2, 3];
215 let b = iter::repeat(&0);
216
217 assert_eq!(a.iter().size_hint(), (3, Some(3)), "Sanity check failed");
218 assert_eq!(b.size_hint(), (usize::MAX, None), "Sanity check failed");
219
220 let iter = a.iter().alternate_with_all(b);
221
222 assert_eq!(iter.size_hint(), (usize::MAX, None));
223 }
224 #[test]
225 fn size_hint_unbounded_left() {
226 let a = iter::repeat(&0);
227 let b = [1, 2, 3];
228
229 assert_eq!(a.size_hint(), (usize::MAX, None), "Sanity check failed");
230 assert_eq!(b.iter().size_hint(), (3, Some(3)), "Sanity check failed");
231
232 let iter = a.alternate_with_all(b.iter());
233
234 assert_eq!(iter.size_hint(), (usize::MAX, None));
235 }
236 #[test]
237 fn size_hint_bound_exceed_max() {
238 let a = 0..usize::MAX;
239 let b = 0..3;
240
241 assert_eq!(
242 a.size_hint(),
243 (usize::MAX, Some(usize::MAX)),
244 "Sanity check failed"
245 );
246 assert_eq!(b.size_hint(), (3, Some(3)), "Sanity check failed");
247
248 let iter = a.alternate_with_all(b);
249
250 assert_eq!(iter.size_hint(), (usize::MAX, None));
251 }
252 #[test]
253 fn size_hint_bound_exactly_max() {
254 let a = 0..usize::MAX;
255 let b = 0..0;
256
257 assert_eq!(
258 a.size_hint(),
259 (usize::MAX, Some(usize::MAX)),
260 "Sanity check failed"
261 );
262 assert_eq!(b.size_hint(), (0, Some(0)), "Sanity check failed");
263
264 let iter = a.alternate_with_all(b);
265
266 assert_eq!(iter.size_hint(), (usize::MAX, Some(usize::MAX)));
267 }
268}