par_iter/iter/
interleave_shortest.rs

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