Rollup merge of #74707 - matklad:split_once, r=dtolnay
Add str::[r]split_once This is useful for quick&dirty parsing of key: value config pairs. Used a bunch in Cargo and rust-analyzer: * https://github.com/rust-lang/cargo/search?q=splitn%282&unscoped_q=splitn%282 * https://github.com/rust-analyzer/rust-analyzer/search?q=split_delim&unscoped_q=split_delim In theory, once const-generics are done, this functionality could be achieved without a dedicated method with ```rust match s.splitn(delimier, 2).collect_array::<2>() { Some([prefix, suffix]) => todo!(), None => todo!(), } ``` Even in that world, having a dedicated method seems clearer on the intention. I am not sure about naming -- this is something I've just came up with yesterday, I don't know off the top of my head analogs in other languages. If T-libs thinks this is a reasonable API to have, I'll open a tracking issue and add more thorough tests.
This commit is contained in:
commit
6968b75bd0
3 changed files with 66 additions and 0 deletions
|
@ -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)]
|
||||
|
|
|
@ -1318,6 +1318,30 @@ fn test_rsplitn() {
|
|||
assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
|
||||
}
|
||||
|
||||
#[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";
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
Loading…
Add table
Reference in a new issue