Repository: rayon-rs/rayon
Pull request #1117 (2024-01-26 20:44:56)

`impl Pattern for [char; N]` and `&[char; N]`
This matches the addition in rust-lang/rust#86336.


Patch:
diff --git a/src/str.rs b/src/str.rs
index c85754e..e9efc98 100644
--- a/src/str.rs
+++ b/src/str.rs
@@ -6,8 +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`, `&[char]`, and any function or closure
-//! `F: Fn(char) -> bool + Sync + Send`.
+//! It is implemented for `char`, `&[char]`, `[char; N]`, `&[char; N]`,
+//! 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
@@ -140,8 +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`, `&[char]`, and any function or closure
-    /// `F: Fn(char) -> bool + Sync + Send`.
+    /// It is implemented for `char`, `&[char]`, `[char; N]`, `&[char; N]`,
+    /// and any function or closure `F: Fn(char) -> bool + Sync + Send`.
     ///
     /// # Examples
     ///
@@ -163,8 +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`, `&[char]`, and any function or closure
-    /// `F: Fn(char) -> bool + Sync + Send`.
+    /// It is implemented for `char`, `&[char]`, `[char; N]`, `&[char; N]`,
+    /// and any function or closure `F: Fn(char) -> bool + Sync + Send`.
     ///
     /// # Examples
     ///
@@ -221,8 +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`, `&[char]`, and any function or closure
-    /// `F: Fn(char) -> bool + Sync + Send`.
+    /// It is implemented for `char`, `&[char]`, `[char; N]`, `&[char; N]`,
+    /// and any function or closure `F: Fn(char) -> bool + Sync + Send`.
     ///
     /// # Examples
     ///
@@ -245,8 +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`, `&[char]`, and any function or closure
-    /// `F: Fn(char) -> bool + Sync + Send`.
+    /// It is implemented for `char`, `&[char]`, `[char; N]`, `&[char; N]`,
+    /// and any function or closure `F: Fn(char) -> bool + Sync + Send`.
     ///
     /// # Examples
     ///
@@ -362,6 +362,17 @@ impl Pattern for &[char] {
     impl_pattern!(&self => *self);
 }
 
+// TODO (MSRV 1.75): use `*self` for array patterns too.
+// - Needs `DoubleEndedSearcher` so `split.next_back()` works.
+
+impl<const N: usize> Pattern for [char; N] {
+    impl_pattern!(&self => self.as_slice());
+}
+
+impl<const N: usize> Pattern for &[char; N] {
+    impl_pattern!(&self => self.as_slice());
+}
+
 impl<FN: Sync + Send + Fn(char) -> bool> Pattern for FN {
     impl_pattern!(&self => self);
 }


Test patch:
diff --git a/tests/str.rs b/tests/str.rs
index f73a261..a08b31a 100644
--- a/tests/str.rs
+++ b/tests/str.rs
@@ -59,35 +59,38 @@ pub fn execute_strings_split() {
         (include_str!("str.rs"), ' '),
     ];
 
-    for &(string, separator) in &tests {
-        let serial: Vec<_> = string.split(separator).collect();
-        let parallel: Vec<_> = string.par_split(separator).collect();
-        assert_eq!(serial, parallel);
-
-        let pattern: &[char] = &['\u{0}', separator, '\u{1F980}'];
-        let serial: Vec<_> = string.split(pattern).collect();
-        let parallel: Vec<_> = string.par_split(pattern).collect();
-        assert_eq!(serial, parallel);
-
-        let serial_fn: Vec<_> = string.split(|c| c == separator).collect();
-        let parallel_fn: Vec<_> = string.par_split(|c| c == separator).collect();
-        assert_eq!(serial_fn, parallel_fn);
+    macro_rules! check_separators {
+        ($split:ident, $par_split:ident) => {
+            for &(string, separator) in &tests {
+                let serial: Vec<_> = string.$split(separator).collect();
+                let parallel: Vec<_> = string.$par_split(separator).collect();
+                assert_eq!(serial, parallel);
+
+                let array = ['\u{0}', separator, '\u{1F980}'];
+                let array_ref = &array;
+                let slice: &[char] = array_ref;
+
+                let serial: Vec<_> = string.$split(slice).collect();
+                let parallel: Vec<_> = string.$par_split(slice).collect();
+                assert_eq!(serial, parallel);
+
+                let serial: Vec<_> = string.$split(array).collect();
+                let parallel: Vec<_> = string.$par_split(array).collect();
+                assert_eq!(serial, parallel);
+
+                let serial: Vec<_> = string.$split(array_ref).collect();
+                let parallel: Vec<_> = string.$par_split(array_ref).collect();
+                assert_eq!(serial, parallel);
+
+                let serial_fn: Vec<_> = string.$split(|c| c == separator).collect();
+                let parallel_fn: Vec<_> = string.$par_split(|c| c == separator).collect();
+                assert_eq!(serial_fn, parallel_fn);
+            }
+        };
     }
 
-    for &(string, separator) in &tests {
-        let serial: Vec<_> = string.split_terminator(separator).collect();
-        let parallel: Vec<_> = string.par_split_terminator(separator).collect();
-        assert_eq!(serial, parallel);
-
-        let pattern: &[char] = &['\u{0}', separator, '\u{1F980}'];
-        let serial: Vec<_> = string.split_terminator(pattern).collect();
-        let parallel: Vec<_> = string.par_split_terminator(pattern).collect();
-        assert_eq!(serial, parallel);
-
-        let serial: Vec<_> = string.split_terminator(|c| c == separator).collect();
-        let parallel: Vec<_> = string.par_split_terminator(|c| c == separator).collect();
-        assert_eq!(serial, parallel);
-    }
+    check_separators!(split, par_split);
+    check_separators!(split_terminator, par_split_terminator);
 
     for &(string, _) in &tests {
         let serial: Vec<_> = string.lines().collect();
@@ -102,33 +105,6 @@ pub fn execute_strings_split() {
     }
 
     // try matching separators too!
-    for &(string, separator) in &tests {
-        let serial: Vec<_> = string.matches(separator).collect();
-        let parallel: Vec<_> = string.par_matches(separator).collect();
-        assert_eq!(serial, parallel);
-
-        let pattern: &[char] = &['\u{0}', separator, '\u{1F980}'];
-        let serial: Vec<_> = string.matches(pattern).collect();
-        let parallel: Vec<_> = string.par_matches(pattern).collect();
-        assert_eq!(serial, parallel);
-
-        let serial_fn: Vec<_> = string.matches(|c| c == separator).collect();
-        let parallel_fn: Vec<_> = string.par_matches(|c| c == separator).collect();
-        assert_eq!(serial_fn, parallel_fn);
-    }
-
-    for &(string, separator) in &tests {
-        let serial: Vec<_> = string.match_indices(separator).collect();
-        let parallel: Vec<_> = string.par_match_indices(separator).collect();
-        assert_eq!(serial, parallel);
-
-        let pattern: &[char] = &['\u{0}', separator, '\u{1F980}'];
-        let serial: Vec<_> = string.match_indices(pattern).collect();
-        let parallel: Vec<_> = string.par_match_indices(pattern).collect();
-        assert_eq!(serial, parallel);
-
-        let serial_fn: Vec<_> = string.match_indices(|c| c == separator).collect();
-        let parallel_fn: Vec<_> = string.par_match_indices(|c| c == separator).collect();
-        assert_eq!(serial_fn, parallel_fn);
-    }
+    check_separators!(matches, par_matches);
+    check_separators!(match_indices, par_match_indices);
 }