use super::plumbing::*; use super::*; use std::cmp; /// `MinLen` is an iterator that imposes a minimum length on iterator splits. /// This struct is created by the [`min_len()`] method on [`IndexedParallelIterator`] /// /// [`min_len()`]: trait.IndexedParallelIterator.html#method.min_len /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[derive(Debug, Clone)] pub struct MinLen { base: I, min: usize, } impl MinLen where I: IndexedParallelIterator, { /// Creates a new `MinLen` iterator. pub(super) fn new(base: I, min: usize) -> Self { MinLen { base, min } } } impl ParallelIterator for MinLen where I: IndexedParallelIterator, { type Item = I::Item; fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, { bridge(self, consumer) } fn opt_len(&self) -> Option { Some(self.len()) } } impl IndexedParallelIterator for MinLen where I: IndexedParallelIterator, { fn drive>(self, consumer: C) -> C::Result { bridge(self, consumer) } fn len(&self) -> usize { self.base.len() } fn with_producer(self, callback: CB) -> CB::Output where CB: ProducerCallback, { return self.base.with_producer(Callback { callback, min: self.min, }); struct Callback { callback: CB, min: usize, } impl ProducerCallback for Callback where CB: ProducerCallback, { type Output = CB::Output; fn callback

(self, base: P) -> CB::Output where P: Producer, { let producer = MinLenProducer { base, min: self.min, }; self.callback.callback(producer) } } } } /// //////////////////////////////////////////////////////////////////////// /// `MinLenProducer` implementation struct MinLenProducer

{ base: P, min: usize, } impl

Producer for MinLenProducer

where P: Producer, { type Item = P::Item; type IntoIter = P::IntoIter; fn into_iter(self) -> Self::IntoIter { self.base.into_iter() } fn min_len(&self) -> usize { cmp::max(self.min, self.base.min_len()) } fn max_len(&self) -> usize { self.base.max_len() } fn split_at(self, index: usize) -> (Self, Self) { let (left, right) = self.base.split_at(index); ( MinLenProducer { base: left, min: self.min, }, MinLenProducer { base: right, min: self.min, }, ) } fn fold_with(self, folder: F) -> F where F: Folder, { self.base.fold_with(folder) } } /// `MaxLen` is an iterator that imposes a maximum length on iterator splits. /// This struct is created by the [`max_len()`] method on [`IndexedParallelIterator`] /// /// [`max_len()`]: trait.IndexedParallelIterator.html#method.max_len /// [`IndexedParallelIterator`]: trait.IndexedParallelIterator.html #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] #[derive(Debug, Clone)] pub struct MaxLen { base: I, max: usize, } impl MaxLen where I: IndexedParallelIterator, { /// Creates a new `MaxLen` iterator. pub(super) fn new(base: I, max: usize) -> Self { MaxLen { base, max } } } impl ParallelIterator for MaxLen where I: IndexedParallelIterator, { type Item = I::Item; fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, { bridge(self, consumer) } fn opt_len(&self) -> Option { Some(self.len()) } } impl IndexedParallelIterator for MaxLen where I: IndexedParallelIterator, { fn drive>(self, consumer: C) -> C::Result { bridge(self, consumer) } fn len(&self) -> usize { self.base.len() } fn with_producer(self, callback: CB) -> CB::Output where CB: ProducerCallback, { return self.base.with_producer(Callback { callback, max: self.max, }); struct Callback { callback: CB, max: usize, } impl ProducerCallback for Callback where CB: ProducerCallback, { type Output = CB::Output; fn callback

(self, base: P) -> CB::Output where P: Producer, { let producer = MaxLenProducer { base, max: self.max, }; self.callback.callback(producer) } } } } /// //////////////////////////////////////////////////////////////////////// /// `MaxLenProducer` implementation struct MaxLenProducer

{ base: P, max: usize, } impl

Producer for MaxLenProducer

where P: Producer, { type Item = P::Item; type IntoIter = P::IntoIter; fn into_iter(self) -> Self::IntoIter { self.base.into_iter() } fn min_len(&self) -> usize { self.base.min_len() } fn max_len(&self) -> usize { cmp::min(self.max, self.base.max_len()) } fn split_at(self, index: usize) -> (Self, Self) { let (left, right) = self.base.split_at(index); ( MaxLenProducer { base: left, max: self.max, }, MaxLenProducer { base: right, max: self.max, }, ) } fn fold_with(self, folder: F) -> F where F: Folder, { self.base.fold_with(folder) } }