Skip to content

Commit f7febc8

Browse files
authored
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 #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`
2 parents ae1a2df + d4fd853 commit f7febc8

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

library/core/src/iter/adapters/filter.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use crate::ops::Try;
1313
#[stable(feature = "rust1", since = "1.0.0")]
1414
#[derive(Clone)]
1515
pub struct Filter<I, P> {
16-
iter: I,
16+
// Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods
17+
pub(crate) iter: I,
1718
predicate: P,
1819
}
1920
impl<I, P> Filter<I, P> {

library/core/src/iter/adapters/map.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ use crate::ops::Try;
5757
#[stable(feature = "rust1", since = "1.0.0")]
5858
#[derive(Clone)]
5959
pub struct Map<I, F> {
60-
iter: I,
60+
// Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods
61+
pub(crate) iter: I,
6162
f: F,
6263
}
6364

library/core/src/slice/iter.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,11 @@ pub struct Split<'a, T: 'a, P>
335335
where
336336
P: FnMut(&T) -> bool,
337337
{
338-
v: &'a [T],
338+
// Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods
339+
pub(crate) v: &'a [T],
339340
pred: P,
340-
finished: bool,
341+
// Used for `SplitAsciiWhitespace` `as_str` method
342+
pub(crate) finished: bool,
341343
}
342344

343345
impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> {

library/core/src/str/iter.rs

+53
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,30 @@ impl<'a> DoubleEndedIterator for SplitWhitespace<'a> {
12001200
#[stable(feature = "fused", since = "1.26.0")]
12011201
impl FusedIterator for SplitWhitespace<'_> {}
12021202

1203+
impl<'a> SplitWhitespace<'a> {
1204+
/// Returns remainder of the splitted string
1205+
///
1206+
/// # Examples
1207+
///
1208+
/// ```
1209+
/// #![feature(str_split_whitespace_as_str)]
1210+
///
1211+
/// let mut split = "Mary had a little lamb".split_whitespace();
1212+
/// assert_eq!(split.as_str(), "Mary had a little lamb");
1213+
///
1214+
/// split.next();
1215+
/// assert_eq!(split.as_str(), "had a little lamb");
1216+
///
1217+
/// split.by_ref().for_each(drop);
1218+
/// assert_eq!(split.as_str(), "");
1219+
/// ```
1220+
#[inline]
1221+
#[unstable(feature = "str_split_whitespace_as_str", issue = "77998")]
1222+
pub fn as_str(&self) -> &'a str {
1223+
self.inner.iter.as_str()
1224+
}
1225+
}
1226+
12031227
#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
12041228
impl<'a> Iterator for SplitAsciiWhitespace<'a> {
12051229
type Item = &'a str;
@@ -1231,6 +1255,35 @@ impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> {
12311255
#[stable(feature = "split_ascii_whitespace", since = "1.34.0")]
12321256
impl FusedIterator for SplitAsciiWhitespace<'_> {}
12331257

1258+
impl<'a> SplitAsciiWhitespace<'a> {
1259+
/// Returns remainder of the splitted string
1260+
///
1261+
/// # Examples
1262+
///
1263+
/// ```
1264+
/// #![feature(str_split_whitespace_as_str)]
1265+
///
1266+
/// let mut split = "Mary had a little lamb".split_ascii_whitespace();
1267+
/// assert_eq!(split.as_str(), "Mary had a little lamb");
1268+
///
1269+
/// split.next();
1270+
/// assert_eq!(split.as_str(), "had a little lamb");
1271+
///
1272+
/// split.by_ref().for_each(drop);
1273+
/// assert_eq!(split.as_str(), "");
1274+
/// ```
1275+
#[inline]
1276+
#[unstable(feature = "str_split_whitespace_as_str", issue = "77998")]
1277+
pub fn as_str(&self) -> &'a str {
1278+
if self.inner.iter.iter.finished {
1279+
return "";
1280+
}
1281+
1282+
// SAFETY: Slice is created from str.
1283+
unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) }
1284+
}
1285+
}
1286+
12341287
#[stable(feature = "split_inclusive", since = "1.51.0")]
12351288
impl<'a, P: Pattern<'a>> Iterator for SplitInclusive<'a, P> {
12361289
type Item = &'a str;

0 commit comments

Comments
 (0)