diff options
Diffstat (limited to 'src/str.rs')
-rw-r--r-- | src/str.rs | 142 |
1 files changed, 58 insertions, 84 deletions
@@ -6,7 +6,8 @@ //! Note: [`ParallelString::par_split()`] and [`par_split_terminator()`] //! reference a `Pattern` trait which is not visible outside this crate. //! This trait is intentionally kept private, for use only by Rayon itself. -//! It is implemented for `char` and any `F: Fn(char) -> bool + Sync + Send`. +//! It is implemented for `char`, `&[char]`, and any function or closure +//! `F: Fn(char) -> bool + Sync + Send`. //! //! [`ParallelString::par_split()`]: trait.ParallelString.html#method.par_split //! [`par_split_terminator()`]: trait.ParallelString.html#method.par_split_terminator @@ -34,11 +35,11 @@ fn find_char_midpoint(chars: &str) -> usize { // character boundary. So we look at the raw bytes, first scanning // forward from the midpoint for a boundary, then trying backward. let (left, right) = chars.as_bytes().split_at(mid); - match right.iter().cloned().position(is_char_boundary) { + match right.iter().copied().position(is_char_boundary) { Some(i) => mid + i, None => left .iter() - .cloned() + .copied() .rposition(is_char_boundary) .unwrap_or(0), } @@ -96,7 +97,7 @@ pub trait ParallelString { /// Note that multi-byte sequences (for code points greater than `U+007F`) /// are produced as separate items, but will not be split across threads. /// If you would prefer an indexed iterator without that guarantee, consider - /// `string.as_bytes().par_iter().cloned()` instead. + /// `string.as_bytes().par_iter().copied()` instead. /// /// # Examples /// @@ -139,7 +140,8 @@ pub trait ParallelString { /// given character or predicate, similar to `str::split`. /// /// Note: the `Pattern` trait is private, for use only by Rayon itself. - /// It is implemented for `char` and any `F: Fn(char) -> bool + Sync + Send`. + /// It is implemented for `char`, `&[char]`, and any function or closure + /// `F: Fn(char) -> bool + Sync + Send`. /// /// # Examples /// @@ -161,7 +163,8 @@ pub trait ParallelString { /// substring after a trailing terminator. /// /// Note: the `Pattern` trait is private, for use only by Rayon itself. - /// It is implemented for `char` and any `F: Fn(char) -> bool + Sync + Send`. + /// It is implemented for `char`, `&[char]`, and any function or closure + /// `F: Fn(char) -> bool + Sync + Send`. /// /// # Examples /// @@ -218,7 +221,8 @@ pub trait ParallelString { /// given character or predicate, similar to `str::matches`. /// /// Note: the `Pattern` trait is private, for use only by Rayon itself. - /// It is implemented for `char` and any `F: Fn(char) -> bool + Sync + Send`. + /// It is implemented for `char`, `&[char]`, and any function or closure + /// `F: Fn(char) -> bool + Sync + Send`. /// /// # Examples /// @@ -241,7 +245,8 @@ pub trait ParallelString { /// or predicate, with their positions, similar to `str::match_indices`. /// /// Note: the `Pattern` trait is private, for use only by Rayon itself. - /// It is implemented for `char` and any `F: Fn(char) -> bool + Sync + Send`. + /// It is implemented for `char`, `&[char]`, and any function or closure + /// `F: Fn(char) -> bool + Sync + Send`. /// /// # Examples /// @@ -303,89 +308,62 @@ fn offset<T>(base: usize) -> impl Fn((usize, T)) -> (usize, T) { move |(i, x)| (base + i, x) } -impl Pattern for char { - private_impl! {} +macro_rules! impl_pattern { + (&$self:ident => $pattern:expr) => { + private_impl! {} - #[inline] - fn find_in(&self, chars: &str) -> Option<usize> { - chars.find(*self) - } + #[inline] + fn find_in(&$self, chars: &str) -> Option<usize> { + chars.find($pattern) + } - #[inline] - fn rfind_in(&self, chars: &str) -> Option<usize> { - chars.rfind(*self) - } + #[inline] + fn rfind_in(&$self, chars: &str) -> Option<usize> { + chars.rfind($pattern) + } - #[inline] - fn is_suffix_of(&self, chars: &str) -> bool { - chars.ends_with(*self) - } + #[inline] + fn is_suffix_of(&$self, chars: &str) -> bool { + chars.ends_with($pattern) + } - fn fold_splits<'ch, F>(&self, chars: &'ch str, folder: F, skip_last: bool) -> F - where - F: Folder<&'ch str>, - { - let mut split = chars.split(*self); - if skip_last { - split.next_back(); + fn fold_splits<'ch, F>(&$self, chars: &'ch str, folder: F, skip_last: bool) -> F + where + F: Folder<&'ch str>, + { + let mut split = chars.split($pattern); + if skip_last { + split.next_back(); + } + folder.consume_iter(split) } - folder.consume_iter(split) - } - fn fold_matches<'ch, F>(&self, chars: &'ch str, folder: F) -> F - where - F: Folder<&'ch str>, - { - folder.consume_iter(chars.matches(*self)) - } + fn fold_matches<'ch, F>(&$self, chars: &'ch str, folder: F) -> F + where + F: Folder<&'ch str>, + { + folder.consume_iter(chars.matches($pattern)) + } - fn fold_match_indices<'ch, F>(&self, chars: &'ch str, folder: F, base: usize) -> F - where - F: Folder<(usize, &'ch str)>, - { - folder.consume_iter(chars.match_indices(*self).map(offset(base))) + fn fold_match_indices<'ch, F>(&$self, chars: &'ch str, folder: F, base: usize) -> F + where + F: Folder<(usize, &'ch str)>, + { + folder.consume_iter(chars.match_indices($pattern).map(offset(base))) + } } } -impl<FN: Sync + Send + Fn(char) -> bool> Pattern for FN { - private_impl! {} - - fn find_in(&self, chars: &str) -> Option<usize> { - chars.find(self) - } - - fn rfind_in(&self, chars: &str) -> Option<usize> { - chars.rfind(self) - } - - fn is_suffix_of(&self, chars: &str) -> bool { - chars.ends_with(self) - } - - fn fold_splits<'ch, F>(&self, chars: &'ch str, folder: F, skip_last: bool) -> F - where - F: Folder<&'ch str>, - { - let mut split = chars.split(self); - if skip_last { - split.next_back(); - } - folder.consume_iter(split) - } +impl Pattern for char { + impl_pattern!(&self => *self); +} - fn fold_matches<'ch, F>(&self, chars: &'ch str, folder: F) -> F - where - F: Folder<&'ch str>, - { - folder.consume_iter(chars.matches(self)) - } +impl Pattern for &[char] { + impl_pattern!(&self => *self); +} - fn fold_match_indices<'ch, F>(&self, chars: &'ch str, folder: F, base: usize) -> F - where - F: Folder<(usize, &'ch str)>, - { - folder.consume_iter(chars.match_indices(self).map(offset(base))) - } +impl<FN: Sync + Send + Fn(char) -> bool> Pattern for FN { + impl_pattern!(&self => self); } // ///////////////////////////////////////////////////////////////////////// @@ -711,11 +689,7 @@ pub struct Lines<'ch>(&'ch str); #[inline] fn no_carriage_return(line: &str) -> &str { - if line.ends_with('\r') { - &line[..line.len() - 1] - } else { - line - } + line.strip_suffix('\r').unwrap_or(line) } impl<'ch> ParallelIterator for Lines<'ch> { |