1use super::plumbing::*;
2use super::*;
3
4/// `InterleaveShortest` is an iterator that works similarly to
5/// `Interleave`, but this version stops returning elements once one
6/// of the iterators run out.
7///
8/// This struct is created by the [`interleave_shortest()`] method on
9/// [`IndexedParallelIterator`].
10///
11/// [`interleave_shortest()`]: trait.IndexedParallelIterator.html#method.interleave_shortest
12/// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html
13#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
14#[derive(Debug, Clone)]
15pub struct InterleaveShortest<I, J>
16where
17 I: IndexedParallelIterator,
18 J: IndexedParallelIterator<Item = I::Item>,
19{
20 interleave: Interleave<Take<I>, Take<J>>,
21}
22
23impl<I, J> InterleaveShortest<I, J>
24where
25 I: IndexedParallelIterator,
26 J: IndexedParallelIterator<Item = I::Item>,
27{
28 /// Creates a new `InterleaveShortest` iterator
29 pub(super) fn new(i: I, j: J) -> Self {
30 InterleaveShortest {
31 interleave: if i.len() <= j.len() {
32 // take equal lengths from both iterators
33 let n: usize = i.len();
34 i.take(n).interleave(j.take(n))
35 } else {
36 // take one extra item from the first iterator
37 let n: usize = j.len();
38 i.take(n + 1).interleave(j.take(n))
39 },
40 }
41 }
42}
43
44impl<I, J> ParallelIterator for InterleaveShortest<I, J>
45where
46 I: IndexedParallelIterator,
47 J: IndexedParallelIterator<Item = I::Item>,
48{
49 type Item = I::Item;
50
51 fn drive_unindexed<C>(self, consumer: C) -> C::Result
52 where
53 C: Consumer<I::Item>,
54 {
55 bridge(self, consumer)
56 }
57
58 fn opt_len(&self) -> Option<usize> {
59 Some(self.len())
60 }
61}
62
63impl<I, J> IndexedParallelIterator for InterleaveShortest<I, J>
64where
65 I: IndexedParallelIterator,
66 J: IndexedParallelIterator<Item = I::Item>,
67{
68 fn drive<C>(self, consumer: C) -> C::Result
69 where
70 C: Consumer<Self::Item>,
71 {
72 bridge(self, consumer)
73 }
74
75 fn len(&self) -> usize {
76 self.interleave.len()
77 }
78
79 fn with_producer<CB>(self, callback: CB) -> CB::Output
80 where
81 CB: ProducerCallback<Self::Item>,
82 {
83 self.interleave.with_producer(callback)
84 }
85}
86