]> git.lizzy.rs Git - rust.git/commitdiff
std: Change CharEq to take `&mut self`
authorAlex Crichton <alex@alexcrichton.com>
Tue, 22 Apr 2014 05:21:37 +0000 (22:21 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 23 Apr 2014 17:03:43 +0000 (10:03 -0700)
This is similar to the previous commits to allow invocation of a closure through
a `&mut self` pointer because `&self` is disallowed. One of the primary
implementors of the CharEq trait is a closure type, which would not work if the
method continued to have `&self`.

In addition to changing mutability of the `matches` method, this modifies the
following methods from &CharEq to take a type which implements CharEq by value.

* trim_chars
* trim_left_chars
* trim_right_chars

Where these methods were previously invoked via

    s.trim_chars(&'a')

it would now be invoked through

    s.trim_chars('a')

[breaking-change]

src/libstd/str.rs

index 672442bb931f43cded1ace0aa44560f00c255fb0..64d2007ad1573d2d042394856d14c5cfe0b1a69a 100644 (file)
@@ -217,7 +217,7 @@ fn connect(&self, sep: &str) -> ~str {
 /// Something that can be used to compare against a character
 pub trait CharEq {
     /// Determine if the splitter should split at the given character
-    fn matches(&self, char) -> bool;
+    fn matches(&mut self, char) -> bool;
     /// Indicate if this is only concerned about ASCII characters,
     /// which can allow for a faster implementation.
     fn only_ascii(&self) -> bool;
@@ -225,29 +225,29 @@ pub trait CharEq {
 
 impl CharEq for char {
     #[inline]
-    fn matches(&self, c: char) -> bool { *self == c }
+    fn matches(&mut self, c: char) -> bool { *self == c }
 
     fn only_ascii(&self) -> bool { (*self as uint) < 128 }
 }
 
 impl<'a> CharEq for |char|: 'a -> bool {
     #[inline]
-    fn matches(&self, c: char) -> bool { (*self)(c) }
+    fn matches(&mut self, c: char) -> bool { (*self)(c) }
 
     fn only_ascii(&self) -> bool { false }
 }
 
 impl CharEq for extern "Rust" fn(char) -> bool {
     #[inline]
-    fn matches(&self, c: char) -> bool { (*self)(c) }
+    fn matches(&mut self, c: char) -> bool { (*self)(c) }
 
     fn only_ascii(&self) -> bool { false }
 }
 
-impl<'a, C: CharEq> CharEq for &'a [C] {
+impl<'a> CharEq for &'a [char] {
     #[inline]
-    fn matches(&self, c: char) -> bool {
-        self.iter().any(|m| m.matches(c))
+    fn matches(&mut self, c: char) -> bool {
+        self.iter().any(|&mut m| m.matches(c))
     }
 
     fn only_ascii(&self) -> bool {
@@ -1977,11 +1977,11 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar")
-    /// assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar")
-    /// assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar")
+    /// assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar")
+    /// assert_eq!("12foo1bar12".trim_chars(&['1', '2']), "foo1bar")
+    /// assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_digit()), "foo1bar")
     /// ```
-    fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
+    fn trim_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
 
     /// Returns a string with leading `chars_to_trim` removed.
     ///
@@ -1992,11 +1992,11 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11")
-    /// assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12")
-    /// assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123")
+    /// assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11")
+    /// assert_eq!("12foo1bar12".trim_left_chars(&['1', '2']), "foo1bar12")
+    /// assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_digit()), "foo1bar123")
     /// ```
-    fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
+    fn trim_left_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
 
     /// Returns a string with trailing `chars_to_trim` removed.
     ///
@@ -2007,11 +2007,11 @@ pub trait StrSlice<'a> {
     /// # Example
     ///
     /// ```rust
-    /// assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar")
-    /// assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar")
-    /// assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar")
+    /// assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar")
+    /// assert_eq!("12foo1bar12".trim_right_chars(&['1', '2']), "12foo1bar")
+    /// assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_digit()), "123foo1bar")
     /// ```
-    fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
+    fn trim_right_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
 
     /// Replace all occurrences of one string with another.
     ///
@@ -2487,21 +2487,31 @@ fn trim(&self) -> &'a str {
 
     #[inline]
     fn trim_left(&self) -> &'a str {
-        self.trim_left_chars(&char::is_whitespace)
+        self.trim_left_chars(char::is_whitespace)
     }
 
     #[inline]
     fn trim_right(&self) -> &'a str {
-        self.trim_right_chars(&char::is_whitespace)
+        self.trim_right_chars(char::is_whitespace)
     }
 
     #[inline]
-    fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
-        self.trim_left_chars(to_trim).trim_right_chars(to_trim)
+    fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
+        let cur = match self.find(|c: char| !to_trim.matches(c)) {
+            None => "",
+            Some(i) => unsafe { raw::slice_bytes(*self, i, self.len()) }
+        };
+        match cur.rfind(|c: char| !to_trim.matches(c)) {
+            None => "",
+            Some(i) => {
+                let right = cur.char_range_at(i).next;
+                unsafe { raw::slice_bytes(cur, 0, right) }
+            }
+        }
     }
 
     #[inline]
-    fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
+    fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
         match self.find(|c: char| !to_trim.matches(c)) {
             None => "",
             Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) }
@@ -2509,7 +2519,7 @@ fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
     }
 
     #[inline]
-    fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
+    fn trim_right_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
         match self.rfind(|c: char| !to_trim.matches(c)) {
             None => "",
             Some(last) => {
@@ -2627,7 +2637,7 @@ fn as_bytes(&self) -> &'a [u8] {
         unsafe { cast::transmute(*self) }
     }
 
-    fn find<C: CharEq>(&self, search: C) -> Option<uint> {
+    fn find<C: CharEq>(&self, mut search: C) -> Option<uint> {
         if search.only_ascii() {
             self.bytes().position(|b| search.matches(b as char))
         } else {
@@ -2638,7 +2648,7 @@ fn find<C: CharEq>(&self, search: C) -> Option<uint> {
         }
     }
 
-    fn rfind<C: CharEq>(&self, search: C) -> Option<uint> {
+    fn rfind<C: CharEq>(&self, mut search: C) -> Option<uint> {
         if search.only_ascii() {
             self.bytes().rposition(|b| search.matches(b as char))
         } else {
@@ -3156,40 +3166,40 @@ fn test_slice_to() {
     #[test]
     fn test_trim_left_chars() {
         let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_left_chars(&v), " *** foo *** ");
-        assert_eq!(" *** foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
-        assert_eq!(" ***  *** ".trim_left_chars(& &['*', ' ']), "");
-        assert_eq!("foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
+        assert_eq!(" *** foo *** ".trim_left_chars(v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_left_chars(&['*', ' ']), "foo *** ");
+        assert_eq!(" ***  *** ".trim_left_chars(&['*', ' ']), "");
+        assert_eq!("foo *** ".trim_left_chars(&['*', ' ']), "foo *** ");
 
-        assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11");
-        assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12");
-        assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123");
+        assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11");
+        assert_eq!("12foo1bar12".trim_left_chars(&['1', '2']), "foo1bar12");
+        assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_digit()), "foo1bar123");
     }
 
     #[test]
     fn test_trim_right_chars() {
         let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_right_chars(&v), " *** foo *** ");
-        assert_eq!(" *** foo *** ".trim_right_chars(& &['*', ' ']), " *** foo");
-        assert_eq!(" ***  *** ".trim_right_chars(& &['*', ' ']), "");
-        assert_eq!(" *** foo".trim_right_chars(& &['*', ' ']), " *** foo");
+        assert_eq!(" *** foo *** ".trim_right_chars(v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_right_chars(&['*', ' ']), " *** foo");
+        assert_eq!(" ***  *** ".trim_right_chars(&['*', ' ']), "");
+        assert_eq!(" *** foo".trim_right_chars(&['*', ' ']), " *** foo");
 
-        assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar");
-        assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar");
-        assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar");
+        assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar");
+        assert_eq!("12foo1bar12".trim_right_chars(&['1', '2']), "12foo1bar");
+        assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_digit()), "123foo1bar");
     }
 
     #[test]
     fn test_trim_chars() {
         let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_chars(&v), " *** foo *** ");
-        assert_eq!(" *** foo *** ".trim_chars(& &['*', ' ']), "foo");
-        assert_eq!(" ***  *** ".trim_chars(& &['*', ' ']), "");
-        assert_eq!("foo".trim_chars(& &['*', ' ']), "foo");
+        assert_eq!(" *** foo *** ".trim_chars(v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_chars(&['*', ' ']), "foo");
+        assert_eq!(" ***  *** ".trim_chars(&['*', ' ']), "");
+        assert_eq!("foo".trim_chars(&['*', ' ']), "foo");
 
-        assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar");
-        assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar");
-        assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar");
+        assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar");
+        assert_eq!("12foo1bar12".trim_chars(&['1', '2']), "foo1bar");
+        assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_digit()), "foo1bar");
     }
 
     #[test]
@@ -4119,7 +4129,7 @@ fn split_unicode_ascii(b: &mut Bencher) {
     fn split_unicode_not_ascii(b: &mut Bencher) {
         struct NotAscii(char);
         impl CharEq for NotAscii {
-            fn matches(&self, c: char) -> bool {
+            fn matches(&mut self, c: char) -> bool {
                 let NotAscii(cc) = *self;
                 cc == c
             }
@@ -4144,7 +4154,7 @@ fn split_not_ascii(b: &mut Bencher) {
         struct NotAscii(char);
         impl CharEq for NotAscii {
             #[inline]
-            fn matches(&self, c: char) -> bool {
+            fn matches(&mut self, c: char) -> bool {
                 let NotAscii(cc) = *self;
                 cc == c
             }