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