rayon/
string.rs

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}