rayon/iter/
interleave_shortest.rs

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 = 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
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}