par_iter/
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 std::ops::{Range, RangeBounds};
6
7use crate::{iter::plumbing::*, math::simplify_range, prelude::*};
8
9impl<'a> ParallelDrainRange<usize> for &'a mut String {
10    type Item = char;
11    type Iter = Drain<'a>;
12
13    fn par_drain<R: RangeBounds<usize>>(self, range: R) -> Self::Iter {
14        Drain {
15            range: simplify_range(range, self.len()),
16            string: self,
17        }
18    }
19}
20
21/// Draining parallel iterator that moves a range of characters out of a string,
22/// but keeps the total capacity.
23#[derive(Debug)]
24pub struct Drain<'a> {
25    string: &'a mut String,
26    range: Range<usize>,
27}
28
29impl<'a> ParallelIterator for Drain<'a> {
30    type Item = char;
31
32    fn drive_unindexed<C>(self, consumer: C) -> C::Result
33    where
34        C: UnindexedConsumer<Self::Item>,
35    {
36        self.string[self.range.clone()]
37            .par_chars()
38            .drive_unindexed(consumer)
39    }
40}
41
42impl<'a> Drop for Drain<'a> {
43    fn drop(&mut self) {
44        // Remove the drained range.
45        self.string.drain(self.range.clone());
46    }
47}