1 use super::plumbing::*;
2 use 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)]
15 pub struct InterleaveShortest<I, J>
16 where
17     I: IndexedParallelIterator,
18     J: IndexedParallelIterator<Item = I::Item>,
19 {
20     interleave: Interleave<Take<I>, Take<J>>,
21 }
22 
23 impl<I, J> InterleaveShortest<I, J>
24 where
25     I: IndexedParallelIterator,
26     J: IndexedParallelIterator<Item = I::Item>,
27 {
28     /// Creates a new `InterleaveShortest` iterator
new(i: I, j: J) -> Self29     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 = i.len();
34                 i.take(n).interleave(j.take(n))
35             } else {
36                 // take one extra item from the first iterator
37                 let n = j.len();
38                 i.take(n + 1).interleave(j.take(n))
39             },
40         }
41     }
42 }
43 
44 impl<I, J> ParallelIterator for InterleaveShortest<I, J>
45 where
46     I: IndexedParallelIterator,
47     J: IndexedParallelIterator<Item = I::Item>,
48 {
49     type Item = I::Item;
50 
drive_unindexed<C>(self, consumer: C) -> C::Result where C: Consumer<I::Item>,51     fn drive_unindexed<C>(self, consumer: C) -> C::Result
52     where
53         C: Consumer<I::Item>,
54     {
55         bridge(self, consumer)
56     }
57 
opt_len(&self) -> Option<usize>58     fn opt_len(&self) -> Option<usize> {
59         Some(self.len())
60     }
61 }
62 
63 impl<I, J> IndexedParallelIterator for InterleaveShortest<I, J>
64 where
65     I: IndexedParallelIterator,
66     J: IndexedParallelIterator<Item = I::Item>,
67 {
drive<C>(self, consumer: C) -> C::Result where C: Consumer<Self::Item>,68     fn drive<C>(self, consumer: C) -> C::Result
69     where
70         C: Consumer<Self::Item>,
71     {
72         bridge(self, consumer)
73     }
74 
len(&self) -> usize75     fn len(&self) -> usize {
76         self.interleave.len()
77     }
78 
with_producer<CB>(self, callback: CB) -> CB::Output where CB: ProducerCallback<Self::Item>,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