about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAleksey Kladov <aleksey.kladov@gmail.com>2020-07-24 09:39:09 +0200
committerAleksey Kladov <aleksey.kladov@gmail.com>2020-07-28 09:58:20 +0200
commit6e9dc7d9ff806eb3a0b99ffd10892dac8e6f9739 (patch)
tree1ea0e26a8e30fff8e15a3f2d8782ba2e75745ad5
parent1454bbd4fdac9b7272b93fe82860613dccc0afad (diff)
downloadrust-6e9dc7d9ff806eb3a0b99ffd10892dac8e6f9739.tar.gz
rust-6e9dc7d9ff806eb3a0b99ffd10892dac8e6f9739.zip
Add str::[r]split_once
This is useful for quick&dirty parsing of key: value config pairs
-rw-r--r--library/alloc/tests/lib.rs1
-rw-r--r--library/alloc/tests/str.rs24
-rw-r--r--library/core/src/str/mod.rs41
3 files changed, 66 insertions, 0 deletions
diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs
index e2dc816b015..fa20a466715 100644
--- a/library/alloc/tests/lib.rs
+++ b/library/alloc/tests/lib.rs
@@ -6,6 +6,7 @@
 #![feature(map_first_last)]
 #![feature(new_uninit)]
 #![feature(pattern)]
+#![feature(str_split_once)]
 #![feature(trusted_len)]
 #![feature(try_reserve)]
 #![feature(unboxed_closures)]
diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs
index eee98d45340..b20cf076aca 100644
--- a/library/alloc/tests/str.rs
+++ b/library/alloc/tests/str.rs
@@ -1319,6 +1319,30 @@ fn test_rsplitn() {
 }
 
 #[test]
+fn test_split_once() {
+    assert_eq!("".split_once("->"), None);
+    assert_eq!("-".split_once("->"), None);
+    assert_eq!("->".split_once("->"), Some(("", "")));
+    assert_eq!("a->".split_once("->"), Some(("a", "")));
+    assert_eq!("->b".split_once("->"), Some(("", "b")));
+    assert_eq!("a->b".split_once("->"), Some(("a", "b")));
+    assert_eq!("a->b->c".split_once("->"), Some(("a", "b->c")));
+    assert_eq!("---".split_once("--"), Some(("", "-")));
+}
+
+#[test]
+fn test_rsplit_once() {
+    assert_eq!("".rsplit_once("->"), None);
+    assert_eq!("-".rsplit_once("->"), None);
+    assert_eq!("->".rsplit_once("->"), Some(("", "")));
+    assert_eq!("a->".rsplit_once("->"), Some(("a", "")));
+    assert_eq!("->b".rsplit_once("->"), Some(("", "b")));
+    assert_eq!("a->b".rsplit_once("->"), Some(("a", "b")));
+    assert_eq!("a->b->c".rsplit_once("->"), Some(("a->b", "c")));
+    assert_eq!("---".rsplit_once("--"), Some(("-", "")));
+}
+
+#[test]
 fn test_split_whitespace() {
     let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
     let words: Vec<&str> = data.split_whitespace().collect();
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 790ec4bd24f..9d7e38d0e18 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -3610,6 +3610,47 @@ impl str {
         RSplitN(self.splitn(n, pat).0)
     }
 
+    /// Splits the string on the first occurrence of the specified delimiter and
+    /// returns prefix before delimiter and suffix after delimiter.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(str_split_once)]
+    ///
+    /// assert_eq!("cfg".split_once('='), None);
+    /// assert_eq!("cfg=foo".split_once('='), Some(("cfg", "foo")));
+    /// assert_eq!("cfg=foo=bar".split_once('='), Some(("cfg", "foo=bar")));
+    /// ```
+    #[unstable(feature = "str_split_once", reason = "newly added", issue = "74773")]
+    #[inline]
+    pub fn split_once<'a, P: Pattern<'a>>(&'a self, delimiter: P) -> Option<(&'a str, &'a str)> {
+        let (start, end) = delimiter.into_searcher(self).next_match()?;
+        Some((&self[..start], &self[end..]))
+    }
+
+    /// Splits the string on the last occurrence of the specified delimiter and
+    /// returns prefix before delimiter and suffix after delimiter.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(str_split_once)]
+    ///
+    /// assert_eq!("cfg".rsplit_once('='), None);
+    /// assert_eq!("cfg=foo".rsplit_once('='), Some(("cfg", "foo")));
+    /// assert_eq!("cfg=foo=bar".rsplit_once('='), Some(("cfg=foo", "bar")));
+    /// ```
+    #[unstable(feature = "str_split_once", reason = "newly added", issue = "74773")]
+    #[inline]
+    pub fn rsplit_once<'a, P>(&'a self, delimiter: P) -> Option<(&'a str, &'a str)>
+    where
+        P: Pattern<'a, Searcher: ReverseSearcher<'a>>,
+    {
+        let (start, end) = delimiter.into_searcher(self).next_match_back()?;
+        Some((&self[..start], &self[end..]))
+    }
+
     /// An iterator over the disjoint matches of a pattern within the given string
     /// slice.
     ///