diff --git a/library/core/src/iter/adapters/filter.rs b/library/core/src/iter/adapters/filter.rs index f8d684fcdda46..0337892b9e8e1 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 { - iter: I, + // Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods + pub(crate) iter: I, predicate: P, } impl Filter { diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs index 2d997cfe50946..2a4b7efd5e665 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 { - 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 796301c76b608..c82b76df6ff10 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 0c9307a6d2f15..4eac017f9153c 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;