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
5use crate::iter::plumbing::*;
6use crate::math::simplify_range;
7use crate::prelude::*;
8use std::ops::{Range, RangeBounds};
9
10impl<'a> ParallelDrainRange<usize> for &'a mut String {
11 type Iter = Drain<'a>;
12 type Item = char;
13
14 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)]
25pub struct Drain<'a> {
26 string: &'a mut String,
27 range: Range<usize>,
28}
29
30impl<'a> ParallelIterator for Drain<'a> {
31 type Item = char;
32
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
43impl<'a> Drop for Drain<'a> {
44 fn drop(&mut self) {
45 // Remove the drained range.
46 self.string.drain(self.range.clone());
47 }
48}
49