1 //! This module contains the parallel iterator types for owned strings 2 //! (`String`). You will rarely need to interact with it directly 3 //! unless you have need to name one of the iterator types. 4 5 use crate::iter::plumbing::*; 6 use crate::math::simplify_range; 7 use crate::prelude::*; 8 use std::ops::{Range, RangeBounds}; 9 10 impl<'a> ParallelDrainRange<usize> for &'a mut String { 11 type Iter = Drain<'a>; 12 type Item = char; 13 par_drain<R: RangeBounds<usize>>(self, range: R) -> Self::Iter14 fn par_drain<R: RangeBounds<usize>>(self, range: R) -> Self::Iter { 15 Drain { 16 range: simplify_range(range, self.len()), 17 string: self, 18 } 19 } 20 } 21 22 /// Draining parallel iterator that moves a range of characters out of a string, 23 /// but keeps the total capacity. 24 #[derive(Debug)] 25 pub struct Drain<'a> { 26 string: &'a mut String, 27 range: Range<usize>, 28 } 29 30 impl<'a> ParallelIterator for Drain<'a> { 31 type Item = char; 32 drive_unindexed<C>(self, consumer: C) -> C::Result where C: UnindexedConsumer<Self::Item>,33 fn drive_unindexed<C>(self, consumer: C) -> C::Result 34 where 35 C: UnindexedConsumer<Self::Item>, 36 { 37 self.string[self.range.clone()] 38 .par_chars() 39 .drive_unindexed(consumer) 40 } 41 } 42 43 impl<'a> Drop for Drain<'a> { drop(&mut self)44 fn drop(&mut self) { 45 // Remove the drained range. 46 self.string.drain(self.range.clone()); 47 } 48 } 49