diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2021-03-19 23:01:35 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-19 23:01:35 +0100 |
| commit | f7febc8865a2cb2287b034f6588d7617fa0fc6e9 (patch) | |
| tree | 83193b13f7b471f7e129851f49e351d855d43d7e | |
| parent | ae1a2df255d747423d2a7f2be270c7927cf48874 (diff) | |
| parent | d4fd8538cb01f8be6083d2597a294c673f968290 (diff) | |
| download | rust-f7febc8865a2cb2287b034f6588d7617fa0fc6e9.tar.gz rust-f7febc8865a2cb2287b034f6588d7617fa0fc6e9.zip | |
Rollup merge of #82570 - WaffleLapkin:split_whitespace_as_str, r=m-ou-se
Add `as_str` method for split whitespace str iterators This PR adds `as_str` methods to `SplitWhitespace` and `SplitAsciiWhitespace` str iterators. The methods return the remainder, similar to `as_str` methods on `Chars` and other split iterators. This PR is a continuation of https://github.com/rust-lang/rust/pull/75265, which added `as_str` for all other str split iterators. The feature gate for new methods is `#![feature(str_split_whitespace_as_str)]`. `SplitWhitespace` and `SplitAsciiWhitespace` use iterators under the hood, so to implement `as_str` it's required to either 1. Make fields of some iterators `pub(crate)` 2. Add getter methods (like `into_inner`, `inner`, `inner_mut`...) to some (all) iterators 3. Completely rewrite `SplitWhitespace` and `SplitAsciiWhitespace` This PR uses the 1. approach since it's easier to implement and requires fewer changes (and no changes to the public API). If you think that's not the right way, please, tell me. r? `@m-ou-se`
| -rw-r--r-- | library/core/src/iter/adapters/filter.rs | 3 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/map.rs | 3 | ||||
| -rw-r--r-- | library/core/src/slice/iter.rs | 6 | ||||
| -rw-r--r-- | library/core/src/str/iter.rs | 53 |
4 files changed, 61 insertions, 4 deletions
diff --git a/library/core/src/iter/adapters/filter.rs b/library/core/src/iter/adapters/filter.rs index f8d684fcdda..0337892b9e8 100644 --- a/library/core/src/iter/adapters/filter.rs +++ b/library/core/src/iter/adapters/filter.rs @@ -13,7 +13,8 @@ use crate::ops::Try; #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Filter<I, P> { - iter: I, + // Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods + pub(crate) iter: I, predicate: P, } impl<I, P> Filter<I, P> { diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs index 2d997cfe509..2a4b7efd5e6 100644 --- a/library/core/src/iter/adapters/map.rs +++ b/library/core/src/iter/adapters/map.rs @@ -57,7 +57,8 @@ use crate::ops::Try; #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Map<I, F> { - iter: I, + // Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods + pub(crate) iter: I, f: F, } diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 796301c76b6..c82b76df6ff 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -335,9 +335,11 @@ pub struct Split<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - v: &'a [T], + // Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods + pub(crate) v: &'a [T], pred: P, - finished: bool, + // Used for `SplitAsciiWhitespace` `as_str` method + pub(crate) finished: bool, } impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> { diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index 0c9307a6d2f..4eac017f915 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -1200,6 +1200,30 @@ impl<'a> DoubleEndedIterator for SplitWhitespace<'a> { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for SplitWhitespace<'_> {} +impl<'a> SplitWhitespace<'a> { + /// Returns remainder of the splitted string + /// + /// # Examples + /// + /// ``` + /// #![feature(str_split_whitespace_as_str)] + /// + /// let mut split = "Mary had a little lamb".split_whitespace(); + /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// + /// split.next(); + /// assert_eq!(split.as_str(), "had a little lamb"); + /// + /// split.by_ref().for_each(drop); + /// assert_eq!(split.as_str(), ""); + /// ``` + #[inline] + #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")] + pub fn as_str(&self) -> &'a str { + self.inner.iter.as_str() + } +} + #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] impl<'a> Iterator for SplitAsciiWhitespace<'a> { type Item = &'a str; @@ -1231,6 +1255,35 @@ impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> { #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] impl FusedIterator for SplitAsciiWhitespace<'_> {} +impl<'a> SplitAsciiWhitespace<'a> { + /// Returns remainder of the splitted string + /// + /// # Examples + /// + /// ``` + /// #![feature(str_split_whitespace_as_str)] + /// + /// let mut split = "Mary had a little lamb".split_ascii_whitespace(); + /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// + /// split.next(); + /// assert_eq!(split.as_str(), "had a little lamb"); + /// + /// split.by_ref().for_each(drop); + /// assert_eq!(split.as_str(), ""); + /// ``` + #[inline] + #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")] + pub fn as_str(&self) -> &'a str { + if self.inner.iter.iter.finished { + return ""; + } + + // SAFETY: Slice is created from str. + unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) } + } +} + #[stable(feature = "split_inclusive", since = "1.51.0")] impl<'a, P: Pattern<'a>> Iterator for SplitInclusive<'a, P> { type Item = &'a str; |
