diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-04-21 22:21:37 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-04-23 10:03:43 -0700 |
| commit | 2b2d1e14c97b7692debf62dd2739049f1f377a5e (patch) | |
| tree | a7bfb98bc1e31c71e1a1fadfd4896b3dda9a52a1 /src/libstd/str.rs | |
| parent | f4083a22451692b9ae360f3d12bfb8cb52b096e4 (diff) | |
| download | rust-2b2d1e14c97b7692debf62dd2739049f1f377a5e.tar.gz rust-2b2d1e14c97b7692debf62dd2739049f1f377a5e.zip | |
std: Change CharEq to take `&mut self`
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]
Diffstat (limited to 'src/libstd/str.rs')
| -rw-r--r-- | src/libstd/str.rs | 110 |
1 files changed, 60 insertions, 50 deletions
diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 672442bb931..64d2007ad15 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -217,7 +217,7 @@ impl<'a, S: Str> StrVector for Vec<S> { /// 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 @@ impl<'a> StrSlice<'a> for &'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 @@ impl<'a> StrSlice<'a> for &'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 @@ impl<'a> StrSlice<'a> for &'a str { 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 @@ impl<'a> StrSlice<'a> for &'a str { } } - 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 @@ mod tests { #[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 @@ mod bench { 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 @@ mod bench { 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 } |
