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