Skip to content

Commit 8b7f164

Browse files
committed
Auto merge of #52994 - varkor:trim_direction, r=alexcrichton
Add trim_start, trim_end etc.; deprecate trim_left, trim_right, etc. in future Adds the methods: `trim_start`, `trim_end`, `trim_start_matches` and `trim_end_matches`. Deprecates `trim_left`, `trim_right`, `trim_left_matches` and `trim_right_matches` starting from Rust 1.33.0, three versions from when they'll initially be marked as being deprecated, using the future deprecation from #30785 and #51681. Fixes #30459.
2 parents 6e0f1cc + ff79670 commit 8b7f164

File tree

2 files changed

+195
-43
lines changed

2 files changed

+195
-43
lines changed

src/liballoc/tests/str.rs

+38-30
Original file line numberDiff line numberDiff line change
@@ -727,33 +727,33 @@ fn test_is_char_boundary() {
727727
}
728728

729729
#[test]
730-
fn test_trim_left_matches() {
730+
fn test_trim_start_matches() {
731731
let v: &[char] = &[];
732-
assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
732+
assert_eq!(" *** foo *** ".trim_start_matches(v), " *** foo *** ");
733733
let chars: &[char] = &['*', ' '];
734-
assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
735-
assert_eq!(" *** *** ".trim_left_matches(chars), "");
736-
assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
734+
assert_eq!(" *** foo *** ".trim_start_matches(chars), "foo *** ");
735+
assert_eq!(" *** *** ".trim_start_matches(chars), "");
736+
assert_eq!("foo *** ".trim_start_matches(chars), "foo *** ");
737737

738-
assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
738+
assert_eq!("11foo1bar11".trim_start_matches('1'), "foo1bar11");
739739
let chars: &[char] = &['1', '2'];
740-
assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
741-
assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
740+
assert_eq!("12foo1bar12".trim_start_matches(chars), "foo1bar12");
741+
assert_eq!("123foo1bar123".trim_start_matches(|c: char| c.is_numeric()), "foo1bar123");
742742
}
743743

744744
#[test]
745-
fn test_trim_right_matches() {
745+
fn test_trim_end_matches() {
746746
let v: &[char] = &[];
747-
assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
747+
assert_eq!(" *** foo *** ".trim_end_matches(v), " *** foo *** ");
748748
let chars: &[char] = &['*', ' '];
749-
assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
750-
assert_eq!(" *** *** ".trim_right_matches(chars), "");
751-
assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
749+
assert_eq!(" *** foo *** ".trim_end_matches(chars), " *** foo");
750+
assert_eq!(" *** *** ".trim_end_matches(chars), "");
751+
assert_eq!(" *** foo".trim_end_matches(chars), " *** foo");
752752

753-
assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
753+
assert_eq!("11foo1bar11".trim_end_matches('1'), "11foo1bar");
754754
let chars: &[char] = &['1', '2'];
755-
assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
756-
assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
755+
assert_eq!("12foo1bar12".trim_end_matches(chars), "12foo1bar");
756+
assert_eq!("123foo1bar123".trim_end_matches(|c: char| c.is_numeric()), "123foo1bar");
757757
}
758758

759759
#[test]
@@ -772,23 +772,23 @@ fn test_trim_matches() {
772772
}
773773

774774
#[test]
775-
fn test_trim_left() {
776-
assert_eq!("".trim_left(), "");
777-
assert_eq!("a".trim_left(), "a");
778-
assert_eq!(" ".trim_left(), "");
779-
assert_eq!(" blah".trim_left(), "blah");
780-
assert_eq!(" \u{3000} wut".trim_left(), "wut");
781-
assert_eq!("hey ".trim_left(), "hey ");
775+
fn test_trim_start() {
776+
assert_eq!("".trim_start(), "");
777+
assert_eq!("a".trim_start(), "a");
778+
assert_eq!(" ".trim_start(), "");
779+
assert_eq!(" blah".trim_start(), "blah");
780+
assert_eq!(" \u{3000} wut".trim_start(), "wut");
781+
assert_eq!("hey ".trim_start(), "hey ");
782782
}
783783

784784
#[test]
785-
fn test_trim_right() {
786-
assert_eq!("".trim_right(), "");
787-
assert_eq!("a".trim_right(), "a");
788-
assert_eq!(" ".trim_right(), "");
789-
assert_eq!("blah ".trim_right(), "blah");
790-
assert_eq!("wut \u{3000} ".trim_right(), "wut");
791-
assert_eq!(" hey".trim_right(), " hey");
785+
fn test_trim_end() {
786+
assert_eq!("".trim_end(), "");
787+
assert_eq!("a".trim_end(), "a");
788+
assert_eq!(" ".trim_end(), "");
789+
assert_eq!("blah ".trim_end(), "blah");
790+
assert_eq!("wut \u{3000} ".trim_end(), "wut");
791+
assert_eq!(" hey".trim_end(), " hey");
792792
}
793793

794794
#[test]
@@ -1518,12 +1518,20 @@ fn trim_ws() {
15181518
"a \t ");
15191519
assert_eq!(" \t a \t ".trim_right_matches(|c: char| c.is_whitespace()),
15201520
" \t a");
1521+
assert_eq!(" \t a \t ".trim_start_matches(|c: char| c.is_whitespace()),
1522+
"a \t ");
1523+
assert_eq!(" \t a \t ".trim_end_matches(|c: char| c.is_whitespace()),
1524+
" \t a");
15211525
assert_eq!(" \t a \t ".trim_matches(|c: char| c.is_whitespace()),
15221526
"a");
15231527
assert_eq!(" \t \t ".trim_left_matches(|c: char| c.is_whitespace()),
15241528
"");
15251529
assert_eq!(" \t \t ".trim_right_matches(|c: char| c.is_whitespace()),
15261530
"");
1531+
assert_eq!(" \t \t ".trim_start_matches(|c: char| c.is_whitespace()),
1532+
"");
1533+
assert_eq!(" \t \t ".trim_end_matches(|c: char| c.is_whitespace()),
1534+
"");
15271535
assert_eq!(" \t \t ".trim_matches(|c: char| c.is_whitespace()),
15281536
"");
15291537
}

src/libcore/str/mod.rs

+157-13
Original file line numberDiff line numberDiff line change
@@ -3563,6 +3563,76 @@ impl str {
35633563
self.trim_matches(|c: char| c.is_whitespace())
35643564
}
35653565

3566+
/// Returns a string slice with leading whitespace removed.
3567+
///
3568+
/// 'Whitespace' is defined according to the terms of the Unicode Derived
3569+
/// Core Property `White_Space`.
3570+
///
3571+
/// # Text directionality
3572+
///
3573+
/// A string is a sequence of bytes. `start` in this context means the first
3574+
/// position of that byte string; for a left-to-right language like English or
3575+
/// Russian, this will be left side; and for right-to-left languages like
3576+
/// like Arabic or Hebrew, this will be the right side.
3577+
///
3578+
/// # Examples
3579+
///
3580+
/// Basic usage:
3581+
///
3582+
/// ```
3583+
/// let s = " Hello\tworld\t";
3584+
/// assert_eq!("Hello\tworld\t", s.trim_start());
3585+
/// ```
3586+
///
3587+
/// Directionality:
3588+
///
3589+
/// ```
3590+
/// let s = " English ";
3591+
/// assert!(Some('E') == s.trim_start().chars().next());
3592+
///
3593+
/// let s = " עברית ";
3594+
/// assert!(Some('ע') == s.trim_start().chars().next());
3595+
/// ```
3596+
#[stable(feature = "trim_direction", since = "1.30.0")]
3597+
pub fn trim_start(&self) -> &str {
3598+
self.trim_start_matches(|c: char| c.is_whitespace())
3599+
}
3600+
3601+
/// Returns a string slice with trailing whitespace removed.
3602+
///
3603+
/// 'Whitespace' is defined according to the terms of the Unicode Derived
3604+
/// Core Property `White_Space`.
3605+
///
3606+
/// # Text directionality
3607+
///
3608+
/// A string is a sequence of bytes. `end` in this context means the last
3609+
/// position of that byte string; for a left-to-right language like English or
3610+
/// Russian, this will be right side; and for right-to-left languages like
3611+
/// like Arabic or Hebrew, this will be the left side.
3612+
///
3613+
/// # Examples
3614+
///
3615+
/// Basic usage:
3616+
///
3617+
/// ```
3618+
/// let s = " Hello\tworld\t";
3619+
/// assert_eq!(" Hello\tworld", s.trim_end());
3620+
/// ```
3621+
///
3622+
/// Directionality:
3623+
///
3624+
/// ```
3625+
/// let s = " English ";
3626+
/// assert!(Some('h') == s.trim_end().chars().rev().next());
3627+
///
3628+
/// let s = " עברית ";
3629+
/// assert!(Some('ת') == s.trim_end().chars().rev().next());
3630+
/// ```
3631+
#[stable(feature = "trim_direction", since = "1.30.0")]
3632+
pub fn trim_end(&self) -> &str {
3633+
self.trim_end_matches(|c: char| c.is_whitespace())
3634+
}
3635+
35663636
/// Returns a string slice with leading whitespace removed.
35673637
///
35683638
/// 'Whitespace' is defined according to the terms of the Unicode Derived
@@ -3595,8 +3665,9 @@ impl str {
35953665
/// assert!(Some('ע') == s.trim_left().chars().next());
35963666
/// ```
35973667
#[stable(feature = "rust1", since = "1.0.0")]
3668+
#[rustc_deprecated(reason = "superseded by `trim_start`", since = "1.33.0")]
35983669
pub fn trim_left(&self) -> &str {
3599-
self.trim_left_matches(|c: char| c.is_whitespace())
3670+
self.trim_start()
36003671
}
36013672

36023673
/// Returns a string slice with trailing whitespace removed.
@@ -3631,8 +3702,9 @@ impl str {
36313702
/// assert!(Some('ת') == s.trim_right().chars().rev().next());
36323703
/// ```
36333704
#[stable(feature = "rust1", since = "1.0.0")]
3705+
#[rustc_deprecated(reason = "superseded by `trim_end`", since = "1.33.0")]
36343706
pub fn trim_right(&self) -> &str {
3635-
self.trim_right_matches(|c: char| c.is_whitespace())
3707+
self.trim_end()
36363708
}
36373709

36383710
/// Returns a string slice with all prefixes and suffixes that match a
@@ -3697,14 +3769,14 @@ impl str {
36973769
/// Basic usage:
36983770
///
36993771
/// ```
3700-
/// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
3701-
/// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123");
3772+
/// assert_eq!("11foo1bar11".trim_start_matches('1'), "foo1bar11");
3773+
/// assert_eq!("123foo1bar123".trim_start_matches(char::is_numeric), "foo1bar123");
37023774
///
37033775
/// let x: &[_] = &['1', '2'];
3704-
/// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
3776+
/// assert_eq!("12foo1bar12".trim_start_matches(x), "foo1bar12");
37053777
/// ```
3706-
#[stable(feature = "rust1", since = "1.0.0")]
3707-
pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
3778+
#[stable(feature = "trim_direction", since = "1.30.0")]
3779+
pub fn trim_start_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
37083780
let mut i = self.len();
37093781
let mut matcher = pat.into_searcher(self);
37103782
if let Some((a, _)) = matcher.next_reject() {
@@ -3734,20 +3806,20 @@ impl str {
37343806
/// Simple patterns:
37353807
///
37363808
/// ```
3737-
/// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
3738-
/// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar");
3809+
/// assert_eq!("11foo1bar11".trim_end_matches('1'), "11foo1bar");
3810+
/// assert_eq!("123foo1bar123".trim_end_matches(char::is_numeric), "123foo1bar");
37393811
///
37403812
/// let x: &[_] = &['1', '2'];
3741-
/// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
3813+
/// assert_eq!("12foo1bar12".trim_end_matches(x), "12foo1bar");
37423814
/// ```
37433815
///
37443816
/// A more complex pattern, using a closure:
37453817
///
37463818
/// ```
3747-
/// assert_eq!("1fooX".trim_right_matches(|c| c == '1' || c == 'X'), "1foo");
3819+
/// assert_eq!("1fooX".trim_end_matches(|c| c == '1' || c == 'X'), "1foo");
37483820
/// ```
3749-
#[stable(feature = "rust1", since = "1.0.0")]
3750-
pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
3821+
#[stable(feature = "trim_direction", since = "1.30.0")]
3822+
pub fn trim_end_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
37513823
where P::Searcher: ReverseSearcher<'a>
37523824
{
37533825
let mut j = 0;
@@ -3761,6 +3833,78 @@ impl str {
37613833
}
37623834
}
37633835

3836+
/// Returns a string slice with all prefixes that match a pattern
3837+
/// repeatedly removed.
3838+
///
3839+
/// The pattern can be a `&str`, [`char`], or a closure that determines if
3840+
/// a character matches.
3841+
///
3842+
/// [`char`]: primitive.char.html
3843+
///
3844+
/// # Text directionality
3845+
///
3846+
/// A string is a sequence of bytes. 'Left' in this context means the first
3847+
/// position of that byte string; for a language like Arabic or Hebrew
3848+
/// which are 'right to left' rather than 'left to right', this will be
3849+
/// the _right_ side, not the left.
3850+
///
3851+
/// # Examples
3852+
///
3853+
/// Basic usage:
3854+
///
3855+
/// ```
3856+
/// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
3857+
/// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123");
3858+
///
3859+
/// let x: &[_] = &['1', '2'];
3860+
/// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
3861+
/// ```
3862+
#[stable(feature = "rust1", since = "1.0.0")]
3863+
#[rustc_deprecated(reason = "superseded by `trim_start_matches`", since = "1.33.0")]
3864+
pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
3865+
self.trim_start_matches(pat)
3866+
}
3867+
3868+
/// Returns a string slice with all suffixes that match a pattern
3869+
/// repeatedly removed.
3870+
///
3871+
/// The pattern can be a `&str`, [`char`], or a closure that
3872+
/// determines if a character matches.
3873+
///
3874+
/// [`char`]: primitive.char.html
3875+
///
3876+
/// # Text directionality
3877+
///
3878+
/// A string is a sequence of bytes. 'Right' in this context means the last
3879+
/// position of that byte string; for a language like Arabic or Hebrew
3880+
/// which are 'right to left' rather than 'left to right', this will be
3881+
/// the _left_ side, not the right.
3882+
///
3883+
/// # Examples
3884+
///
3885+
/// Simple patterns:
3886+
///
3887+
/// ```
3888+
/// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
3889+
/// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar");
3890+
///
3891+
/// let x: &[_] = &['1', '2'];
3892+
/// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
3893+
/// ```
3894+
///
3895+
/// A more complex pattern, using a closure:
3896+
///
3897+
/// ```
3898+
/// assert_eq!("1fooX".trim_right_matches(|c| c == '1' || c == 'X'), "1foo");
3899+
/// ```
3900+
#[stable(feature = "rust1", since = "1.0.0")]
3901+
#[rustc_deprecated(reason = "superseded by `trim_end_matches`", since = "1.33.0")]
3902+
pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
3903+
where P::Searcher: ReverseSearcher<'a>
3904+
{
3905+
self.trim_end_matches(pat)
3906+
}
3907+
37643908
/// Parses this string slice into another type.
37653909
///
37663910
/// Because `parse` is so general, it can cause problems with type

0 commit comments

Comments
 (0)