Skip to content

Commit

Permalink
Rollup merge of #82570 - WaffleLapkin:split_whitespace_as_str, r=m-ou-se
Browse files Browse the repository at this point in the history
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 #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`
  • Loading branch information
Dylan-DPC authored Mar 19, 2021
2 parents ae1a2df + d4fd853 commit f7febc8
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 4 deletions.
3 changes: 2 additions & 1 deletion library/core/src/iter/adapters/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/iter/adapters/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down
6 changes: 4 additions & 2 deletions library/core/src/slice/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
53 changes: 53 additions & 0 deletions library/core/src/str/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit f7febc8

Please sign in to comment.