From aecf8c2a624d45d1f881caa53c960708cc0f655a Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 21 Jun 2018 14:04:53 +0100 Subject: Add trim_start, trim_end, trim_start_matches and trim_end_matches --- src/libcore/str/mod.rs | 172 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 159 insertions(+), 13 deletions(-) (limited to 'src/libcore/str') diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 86b8349fa3c..eda35519636 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3587,6 +3587,78 @@ impl str { self.trim_matches(|c: char| c.is_whitespace()) } + /// Returns a string slice with leading whitespace removed. + /// + /// 'Whitespace' is defined according to the terms of the Unicode Derived + /// Core Property `White_Space`. + /// + /// # Text directionality + /// + /// A string is a sequence of bytes. `start` in this context means the first + /// position of that byte string; for a left-to-right language like English or + /// Russian, this will be left side; and for right-to-left languages like + /// like Arabic or Hebrew, this will be the right side. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s = " Hello\tworld\t"; + /// + /// assert_eq!("Hello\tworld\t", s.trim_start()); + /// ``` + /// + /// Directionality: + /// + /// ``` + /// let s = " English"; + /// assert!(Some('E') == s.trim_start().chars().next()); + /// + /// let s = " עברית"; + /// assert!(Some('ע') == s.trim_start().chars().next()); + /// ``` + #[unstable(feature = "trim_direction", issue = "30459")] + pub fn trim_start(&self) -> &str { + self.trim_start_matches(|c: char| c.is_whitespace()) + } + + /// Returns a string slice with trailing whitespace removed. + /// + /// 'Whitespace' is defined according to the terms of the Unicode Derived + /// Core Property `White_Space`. + /// + /// # Text directionality + /// + /// A string is a sequence of bytes. `end` in this context means the last + /// position of that byte string; for a left-to-right language like English or + /// Russian, this will be right side; and for right-to-left languages like + /// like Arabic or Hebrew, this will be the left side. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let s = " Hello\tworld\t"; + /// + /// assert_eq!(" Hello\tworld", s.trim_end()); + /// ``` + /// + /// Directionality: + /// + /// ``` + /// let s = "English "; + /// assert!(Some('h') == s.trim_end().chars().rev().next()); + /// + /// let s = "עברית "; + /// assert!(Some('ת') == s.trim_end().chars().rev().next()); + /// ``` + #[unstable(feature = "trim_direction", issue = "30459")] + pub fn trim_end(&self) -> &str { + self.trim_end_matches(|c: char| c.is_whitespace()) + } + /// Returns a string slice with leading whitespace removed. /// /// 'Whitespace' is defined according to the terms of the Unicode Derived @@ -3619,8 +3691,9 @@ impl str { /// assert!(Some('ע') == s.trim_left().chars().next()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_deprecated(reason = "superseded by `trim_start`", since = "1.33.0")] pub fn trim_left(&self) -> &str { - self.trim_left_matches(|c: char| c.is_whitespace()) + self.trim_start() } /// Returns a string slice with trailing whitespace removed. @@ -3655,8 +3728,9 @@ impl str { /// assert!(Some('ת') == s.trim_right().chars().rev().next()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_deprecated(reason = "superseded by `trim_end`", since = "1.33.0")] pub fn trim_right(&self) -> &str { - self.trim_right_matches(|c: char| c.is_whitespace()) + self.trim_end() } /// Returns a string slice with all prefixes and suffixes that match a @@ -3725,14 +3799,14 @@ impl str { /// Basic usage: /// /// ``` - /// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11"); - /// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123"); + /// assert_eq!("11foo1bar11".trim_start_matches('1'), "foo1bar11"); + /// assert_eq!("123foo1bar123".trim_start_matches(char::is_numeric), "foo1bar123"); /// /// let x: &[_] = &['1', '2']; - /// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12"); + /// assert_eq!("12foo1bar12".trim_start_matches(x), "foo1bar12"); /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str { + #[unstable(feature = "trim_direction", issue = "30459")] + pub fn trim_start_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str { let mut i = self.len(); let mut matcher = pat.into_searcher(self); if let Some((a, _)) = matcher.next_reject() { @@ -3764,20 +3838,20 @@ impl str { /// Simple patterns: /// /// ``` - /// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar"); - /// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar"); + /// assert_eq!("11foo1bar11".trim_end_matches('1'), "11foo1bar"); + /// assert_eq!("123foo1bar123".trim_end_matches(char::is_numeric), "123foo1bar"); /// /// let x: &[_] = &['1', '2']; - /// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar"); + /// assert_eq!("12foo1bar12".trim_end_matches(x), "12foo1bar"); /// ``` /// /// A more complex pattern, using a closure: /// /// ``` - /// assert_eq!("1fooX".trim_right_matches(|c| c == '1' || c == 'X'), "1foo"); + /// assert_eq!("1fooX".trim_end_matches(|c| c == '1' || c == 'X'), "1foo"); /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str + #[unstable(feature = "trim_direction", issue = "30459")] + pub fn trim_end_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str where P::Searcher: ReverseSearcher<'a> { let mut j = 0; @@ -3791,6 +3865,78 @@ impl str { } } + /// Returns a string slice with all prefixes that match a pattern + /// repeatedly removed. + /// + /// The pattern can be a `&str`, [`char`], or a closure that determines if + /// a character matches. + /// + /// [`char`]: primitive.char.html + /// + /// # Text directionality + /// + /// A string is a sequence of bytes. 'Left' in this context means the first + /// position of that byte string; for a language like Arabic or Hebrew + /// which are 'right to left' rather than 'left to right', this will be + /// the _right_ side, not the left. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11"); + /// assert_eq!("123foo1bar123".trim_left_matches(char::is_numeric), "foo1bar123"); + /// + /// let x: &[_] = &['1', '2']; + /// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12"); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_deprecated(reason = "superseded by `trim_start_matches`", since = "1.33.0")] + pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str { + self.trim_start_matches(pat) + } + + /// Returns a string slice with all suffixes that match a pattern + /// repeatedly removed. + /// + /// The pattern can be a `&str`, [`char`], or a closure that + /// determines if a character matches. + /// + /// [`char`]: primitive.char.html + /// + /// # Text directionality + /// + /// A string is a sequence of bytes. 'Right' in this context means the last + /// position of that byte string; for a language like Arabic or Hebrew + /// which are 'right to left' rather than 'left to right', this will be + /// the _left_ side, not the right. + /// + /// # Examples + /// + /// Simple patterns: + /// + /// ``` + /// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar"); + /// assert_eq!("123foo1bar123".trim_right_matches(char::is_numeric), "123foo1bar"); + /// + /// let x: &[_] = &['1', '2']; + /// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar"); + /// ``` + /// + /// A more complex pattern, using a closure: + /// + /// ``` + /// assert_eq!("1fooX".trim_right_matches(|c| c == '1' || c == 'X'), "1foo"); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_deprecated(reason = "superseded by `trim_end_matches`", since = "1.33.0")] + pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str + where P::Searcher: ReverseSearcher<'a> + { + self.trim_end_matches(pat) + } + /// Parses this string slice into another type. /// /// Because `parse` is so general, it can cause problems with type -- cgit 1.4.1-3-g733a5 From 33067ad2011ce97e80a247c5a1a9bdb15fc4f376 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 2 Aug 2018 22:00:13 +0100 Subject: Add #![feature(trim_direction)] to doc comments --- src/libcore/str/mod.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/libcore/str') diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index eda35519636..00e296be4f2 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3604,14 +3604,17 @@ impl str { /// Basic usage: /// /// ``` - /// let s = " Hello\tworld\t"; + /// #![feature(trim_direction)] /// + /// let s = " Hello\tworld\t"; /// assert_eq!("Hello\tworld\t", s.trim_start()); /// ``` /// /// Directionality: /// /// ``` + /// #![feature(trim_direction)] + /// /// let s = " English"; /// assert!(Some('E') == s.trim_start().chars().next()); /// @@ -3640,14 +3643,17 @@ impl str { /// Basic usage: /// /// ``` - /// let s = " Hello\tworld\t"; + /// #![feature(trim_direction)] /// + /// let s = " Hello\tworld\t"; /// assert_eq!(" Hello\tworld", s.trim_end()); /// ``` /// /// Directionality: /// /// ``` + /// #![feature(trim_direction)] + /// /// let s = "English "; /// assert!(Some('h') == s.trim_end().chars().rev().next()); /// @@ -3799,6 +3805,8 @@ impl str { /// Basic usage: /// /// ``` + /// #![feature(trim_direction)] + /// /// assert_eq!("11foo1bar11".trim_start_matches('1'), "foo1bar11"); /// assert_eq!("123foo1bar123".trim_start_matches(char::is_numeric), "foo1bar123"); /// @@ -3838,6 +3846,8 @@ impl str { /// Simple patterns: /// /// ``` + /// #![feature(trim_direction)] + /// /// assert_eq!("11foo1bar11".trim_end_matches('1'), "11foo1bar"); /// assert_eq!("123foo1bar123".trim_end_matches(char::is_numeric), "123foo1bar"); /// @@ -3848,6 +3858,8 @@ impl str { /// A more complex pattern, using a closure: /// /// ``` + /// #![feature(trim_direction)] + /// /// assert_eq!("1fooX".trim_end_matches(|c| c == '1' || c == 'X'), "1foo"); /// ``` #[unstable(feature = "trim_direction", issue = "30459")] -- cgit 1.4.1-3-g733a5 From 3e10ffcb81e8f887289904e5aaf272e872a9cb2c Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 5 Aug 2018 21:51:40 +0100 Subject: Make features stable and clarify examples --- src/liballoc/tests/lib.rs | 1 - src/libcore/str/mod.rs | 30 ++++++++---------------------- 2 files changed, 8 insertions(+), 23 deletions(-) (limited to 'src/libcore/str') diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs index 0dcbcf50fb4..618aff963f2 100644 --- a/src/liballoc/tests/lib.rs +++ b/src/liballoc/tests/lib.rs @@ -25,7 +25,6 @@ #![feature(unboxed_closures)] #![feature(exact_chunks)] #![feature(repeat_generic_slice)] -#![feature(trim_direction)] extern crate alloc_system; extern crate core; diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 00e296be4f2..0caab089a3b 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3604,8 +3604,6 @@ impl str { /// Basic usage: /// /// ``` - /// #![feature(trim_direction)] - /// /// let s = " Hello\tworld\t"; /// assert_eq!("Hello\tworld\t", s.trim_start()); /// ``` @@ -3613,15 +3611,13 @@ impl str { /// Directionality: /// /// ``` - /// #![feature(trim_direction)] - /// - /// let s = " English"; + /// let s = " English "; /// assert!(Some('E') == s.trim_start().chars().next()); /// - /// let s = " עברית"; + /// let s = " עברית "; /// assert!(Some('ע') == s.trim_start().chars().next()); /// ``` - #[unstable(feature = "trim_direction", issue = "30459")] + #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_start(&self) -> &str { self.trim_start_matches(|c: char| c.is_whitespace()) } @@ -3643,8 +3639,6 @@ impl str { /// Basic usage: /// /// ``` - /// #![feature(trim_direction)] - /// /// let s = " Hello\tworld\t"; /// assert_eq!(" Hello\tworld", s.trim_end()); /// ``` @@ -3652,15 +3646,13 @@ impl str { /// Directionality: /// /// ``` - /// #![feature(trim_direction)] - /// - /// let s = "English "; + /// let s = " English "; /// assert!(Some('h') == s.trim_end().chars().rev().next()); /// - /// let s = "עברית "; + /// let s = " עברית "; /// assert!(Some('ת') == s.trim_end().chars().rev().next()); /// ``` - #[unstable(feature = "trim_direction", issue = "30459")] + #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_end(&self) -> &str { self.trim_end_matches(|c: char| c.is_whitespace()) } @@ -3805,15 +3797,13 @@ impl str { /// Basic usage: /// /// ``` - /// #![feature(trim_direction)] - /// /// assert_eq!("11foo1bar11".trim_start_matches('1'), "foo1bar11"); /// assert_eq!("123foo1bar123".trim_start_matches(char::is_numeric), "foo1bar123"); /// /// let x: &[_] = &['1', '2']; /// assert_eq!("12foo1bar12".trim_start_matches(x), "foo1bar12"); /// ``` - #[unstable(feature = "trim_direction", issue = "30459")] + #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_start_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str { let mut i = self.len(); let mut matcher = pat.into_searcher(self); @@ -3846,8 +3836,6 @@ impl str { /// Simple patterns: /// /// ``` - /// #![feature(trim_direction)] - /// /// assert_eq!("11foo1bar11".trim_end_matches('1'), "11foo1bar"); /// assert_eq!("123foo1bar123".trim_end_matches(char::is_numeric), "123foo1bar"); /// @@ -3858,11 +3846,9 @@ impl str { /// A more complex pattern, using a closure: /// /// ``` - /// #![feature(trim_direction)] - /// /// assert_eq!("1fooX".trim_end_matches(|c| c == '1' || c == 'X'), "1foo"); /// ``` - #[unstable(feature = "trim_direction", issue = "30459")] + #[stable(feature = "trim_direction", since = "1.30.0")] pub fn trim_end_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str where P::Searcher: ReverseSearcher<'a> { -- cgit 1.4.1-3-g733a5