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()`]: IndexedParallelIterator::interleave_shortest()
12#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
13#[derive(Debug, Clone)]
14pub struct InterleaveShortest<I, J> {
15    interleave: Interleave<Take<I>, Take<J>>,
16}
17
18impl<I, J> InterleaveShortest<I, J>
19where
20    I: IndexedParallelIterator,
21    J: IndexedParallelIterator<Item = I::Item>,
22{
23    /// Creates a new `InterleaveShortest` iterator
24    pub(super) fn new(i: I, j: J) -> Self {
25        InterleaveShortest {
26            interleave: if i.len() <= j.len() {
27                // take equal lengths from both iterators
28                let n = i.len();
29                i.take(n).interleave(j.take(n))
30            } else {
31                // take one extra item from the first iterator
32                let n = j.len();
33                i.take(n + 1).interleave(j.take(n))
34            },
35        }
36    }
37}
38
39impl<I, J> ParallelIterator for InterleaveShortest<I, J>
40where
41    I: IndexedParallelIterator,
42    J: IndexedParallelIterator<Item = I::Item>,
43{
44    type Item = I::Item;
45
46    fn drive_unindexed<C>(self, consumer: C) -> C::Result
47    where
48        C: Consumer<I::Item>,
49    {
50        bridge(self, consumer)
51    }
52
53    fn opt_len(&self) -> Option<usize> {
54        Some(self.len())
55    }
56}
57
58impl<I, J> IndexedParallelIterator for InterleaveShortest<I, J>
59where
60    I: IndexedParallelIterator,
61    J: IndexedParallelIterator<Item = I::Item>,
62{
63    fn drive<C>(self, consumer: C) -> C::Result
64    where
65        C: Consumer<Self::Item>,
66    {
67        bridge(self, consumer)
68    }
69
70    fn len(&self) -> usize {
71        self.interleave.len()
72    }
73
74    fn with_producer<CB>(self, callback: CB) -> CB::Output
75    where
76        CB: ProducerCallback<Self::Item>,
77    {
78        self.interleave.with_producer(callback)
79    }
80}