Skip to content

Commit 2b2d1e1

Browse files
committed
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]
1 parent f4083a2 commit 2b2d1e1

File tree

1 file changed

+60
-50
lines changed

1 file changed

+60
-50
lines changed

src/libstd/str.rs

Lines changed: 60 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -217,37 +217,37 @@ impl<'a, S: Str> StrVector for Vec<S> {
217217
/// Something that can be used to compare against a character
218218
pub trait CharEq {
219219
/// Determine if the splitter should split at the given character
220-
fn matches(&self, char) -> bool;
220+
fn matches(&mut self, char) -> bool;
221221
/// Indicate if this is only concerned about ASCII characters,
222222
/// which can allow for a faster implementation.
223223
fn only_ascii(&self) -> bool;
224224
}
225225

226226
impl CharEq for char {
227227
#[inline]
228-
fn matches(&self, c: char) -> bool { *self == c }
228+
fn matches(&mut self, c: char) -> bool { *self == c }
229229

230230
fn only_ascii(&self) -> bool { (*self as uint) < 128 }
231231
}
232232

233233
impl<'a> CharEq for |char|: 'a -> bool {
234234
#[inline]
235-
fn matches(&self, c: char) -> bool { (*self)(c) }
235+
fn matches(&mut self, c: char) -> bool { (*self)(c) }
236236

237237
fn only_ascii(&self) -> bool { false }
238238
}
239239

240240
impl CharEq for extern "Rust" fn(char) -> bool {
241241
#[inline]
242-
fn matches(&self, c: char) -> bool { (*self)(c) }
242+
fn matches(&mut self, c: char) -> bool { (*self)(c) }
243243

244244
fn only_ascii(&self) -> bool { false }
245245
}
246246

247-
impl<'a, C: CharEq> CharEq for &'a [C] {
247+
impl<'a> CharEq for &'a [char] {
248248
#[inline]
249-
fn matches(&self, c: char) -> bool {
250-
self.iter().any(|m| m.matches(c))
249+
fn matches(&mut self, c: char) -> bool {
250+
self.iter().any(|&mut m| m.matches(c))
251251
}
252252

253253
fn only_ascii(&self) -> bool {
@@ -1977,11 +1977,11 @@ pub trait StrSlice<'a> {
19771977
/// # Example
19781978
///
19791979
/// ```rust
1980-
/// assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar")
1981-
/// assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar")
1982-
/// assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar")
1980+
/// assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar")
1981+
/// assert_eq!("12foo1bar12".trim_chars(&['1', '2']), "foo1bar")
1982+
/// assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_digit()), "foo1bar")
19831983
/// ```
1984-
fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
1984+
fn trim_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
19851985

19861986
/// Returns a string with leading `chars_to_trim` removed.
19871987
///
@@ -1992,11 +1992,11 @@ pub trait StrSlice<'a> {
19921992
/// # Example
19931993
///
19941994
/// ```rust
1995-
/// assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11")
1996-
/// assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12")
1997-
/// assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123")
1995+
/// assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11")
1996+
/// assert_eq!("12foo1bar12".trim_left_chars(&['1', '2']), "foo1bar12")
1997+
/// assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_digit()), "foo1bar123")
19981998
/// ```
1999-
fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
1999+
fn trim_left_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
20002000

20012001
/// Returns a string with trailing `chars_to_trim` removed.
20022002
///
@@ -2007,11 +2007,11 @@ pub trait StrSlice<'a> {
20072007
/// # Example
20082008
///
20092009
/// ```rust
2010-
/// assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar")
2011-
/// assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar")
2012-
/// assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar")
2010+
/// assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar")
2011+
/// assert_eq!("12foo1bar12".trim_right_chars(&['1', '2']), "12foo1bar")
2012+
/// assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_digit()), "123foo1bar")
20132013
/// ```
2014-
fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'a str;
2014+
fn trim_right_chars<C: CharEq>(&self, to_trim: C) -> &'a str;
20152015

20162016
/// Replace all occurrences of one string with another.
20172017
///
@@ -2487,29 +2487,39 @@ impl<'a> StrSlice<'a> for &'a str {
24872487

24882488
#[inline]
24892489
fn trim_left(&self) -> &'a str {
2490-
self.trim_left_chars(&char::is_whitespace)
2490+
self.trim_left_chars(char::is_whitespace)
24912491
}
24922492

24932493
#[inline]
24942494
fn trim_right(&self) -> &'a str {
2495-
self.trim_right_chars(&char::is_whitespace)
2495+
self.trim_right_chars(char::is_whitespace)
24962496
}
24972497

24982498
#[inline]
2499-
fn trim_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
2500-
self.trim_left_chars(to_trim).trim_right_chars(to_trim)
2499+
fn trim_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
2500+
let cur = match self.find(|c: char| !to_trim.matches(c)) {
2501+
None => "",
2502+
Some(i) => unsafe { raw::slice_bytes(*self, i, self.len()) }
2503+
};
2504+
match cur.rfind(|c: char| !to_trim.matches(c)) {
2505+
None => "",
2506+
Some(i) => {
2507+
let right = cur.char_range_at(i).next;
2508+
unsafe { raw::slice_bytes(cur, 0, right) }
2509+
}
2510+
}
25012511
}
25022512

25032513
#[inline]
2504-
fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
2514+
fn trim_left_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
25052515
match self.find(|c: char| !to_trim.matches(c)) {
25062516
None => "",
25072517
Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) }
25082518
}
25092519
}
25102520

25112521
#[inline]
2512-
fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'a str {
2522+
fn trim_right_chars<C: CharEq>(&self, mut to_trim: C) -> &'a str {
25132523
match self.rfind(|c: char| !to_trim.matches(c)) {
25142524
None => "",
25152525
Some(last) => {
@@ -2627,7 +2637,7 @@ impl<'a> StrSlice<'a> for &'a str {
26272637
unsafe { cast::transmute(*self) }
26282638
}
26292639

2630-
fn find<C: CharEq>(&self, search: C) -> Option<uint> {
2640+
fn find<C: CharEq>(&self, mut search: C) -> Option<uint> {
26312641
if search.only_ascii() {
26322642
self.bytes().position(|b| search.matches(b as char))
26332643
} else {
@@ -2638,7 +2648,7 @@ impl<'a> StrSlice<'a> for &'a str {
26382648
}
26392649
}
26402650

2641-
fn rfind<C: CharEq>(&self, search: C) -> Option<uint> {
2651+
fn rfind<C: CharEq>(&self, mut search: C) -> Option<uint> {
26422652
if search.only_ascii() {
26432653
self.bytes().rposition(|b| search.matches(b as char))
26442654
} else {
@@ -3156,40 +3166,40 @@ mod tests {
31563166
#[test]
31573167
fn test_trim_left_chars() {
31583168
let v: &[char] = &[];
3159-
assert_eq!(" *** foo *** ".trim_left_chars(&v), " *** foo *** ");
3160-
assert_eq!(" *** foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
3161-
assert_eq!(" *** *** ".trim_left_chars(& &['*', ' ']), "");
3162-
assert_eq!("foo *** ".trim_left_chars(& &['*', ' ']), "foo *** ");
3169+
assert_eq!(" *** foo *** ".trim_left_chars(v), " *** foo *** ");
3170+
assert_eq!(" *** foo *** ".trim_left_chars(&['*', ' ']), "foo *** ");
3171+
assert_eq!(" *** *** ".trim_left_chars(&['*', ' ']), "");
3172+
assert_eq!("foo *** ".trim_left_chars(&['*', ' ']), "foo *** ");
31633173

3164-
assert_eq!("11foo1bar11".trim_left_chars(&'1'), "foo1bar11");
3165-
assert_eq!("12foo1bar12".trim_left_chars(& &['1', '2']), "foo1bar12");
3166-
assert_eq!("123foo1bar123".trim_left_chars(&|c: char| c.is_digit()), "foo1bar123");
3174+
assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11");
3175+
assert_eq!("12foo1bar12".trim_left_chars(&['1', '2']), "foo1bar12");
3176+
assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_digit()), "foo1bar123");
31673177
}
31683178

31693179
#[test]
31703180
fn test_trim_right_chars() {
31713181
let v: &[char] = &[];
3172-
assert_eq!(" *** foo *** ".trim_right_chars(&v), " *** foo *** ");
3173-
assert_eq!(" *** foo *** ".trim_right_chars(& &['*', ' ']), " *** foo");
3174-
assert_eq!(" *** *** ".trim_right_chars(& &['*', ' ']), "");
3175-
assert_eq!(" *** foo".trim_right_chars(& &['*', ' ']), " *** foo");
3182+
assert_eq!(" *** foo *** ".trim_right_chars(v), " *** foo *** ");
3183+
assert_eq!(" *** foo *** ".trim_right_chars(&['*', ' ']), " *** foo");
3184+
assert_eq!(" *** *** ".trim_right_chars(&['*', ' ']), "");
3185+
assert_eq!(" *** foo".trim_right_chars(&['*', ' ']), " *** foo");
31763186

3177-
assert_eq!("11foo1bar11".trim_right_chars(&'1'), "11foo1bar");
3178-
assert_eq!("12foo1bar12".trim_right_chars(& &['1', '2']), "12foo1bar");
3179-
assert_eq!("123foo1bar123".trim_right_chars(&|c: char| c.is_digit()), "123foo1bar");
3187+
assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar");
3188+
assert_eq!("12foo1bar12".trim_right_chars(&['1', '2']), "12foo1bar");
3189+
assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_digit()), "123foo1bar");
31803190
}
31813191

31823192
#[test]
31833193
fn test_trim_chars() {
31843194
let v: &[char] = &[];
3185-
assert_eq!(" *** foo *** ".trim_chars(&v), " *** foo *** ");
3186-
assert_eq!(" *** foo *** ".trim_chars(& &['*', ' ']), "foo");
3187-
assert_eq!(" *** *** ".trim_chars(& &['*', ' ']), "");
3188-
assert_eq!("foo".trim_chars(& &['*', ' ']), "foo");
3195+
assert_eq!(" *** foo *** ".trim_chars(v), " *** foo *** ");
3196+
assert_eq!(" *** foo *** ".trim_chars(&['*', ' ']), "foo");
3197+
assert_eq!(" *** *** ".trim_chars(&['*', ' ']), "");
3198+
assert_eq!("foo".trim_chars(&['*', ' ']), "foo");
31893199

3190-
assert_eq!("11foo1bar11".trim_chars(&'1'), "foo1bar");
3191-
assert_eq!("12foo1bar12".trim_chars(& &['1', '2']), "foo1bar");
3192-
assert_eq!("123foo1bar123".trim_chars(&|c: char| c.is_digit()), "foo1bar");
3200+
assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar");
3201+
assert_eq!("12foo1bar12".trim_chars(&['1', '2']), "foo1bar");
3202+
assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_digit()), "foo1bar");
31933203
}
31943204

31953205
#[test]
@@ -4119,7 +4129,7 @@ mod bench {
41194129
fn split_unicode_not_ascii(b: &mut Bencher) {
41204130
struct NotAscii(char);
41214131
impl CharEq for NotAscii {
4122-
fn matches(&self, c: char) -> bool {
4132+
fn matches(&mut self, c: char) -> bool {
41234133
let NotAscii(cc) = *self;
41244134
cc == c
41254135
}
@@ -4144,7 +4154,7 @@ mod bench {
41444154
struct NotAscii(char);
41454155
impl CharEq for NotAscii {
41464156
#[inline]
4147-
fn matches(&self, c: char) -> bool {
4157+
fn matches(&mut self, c: char) -> bool {
41484158
let NotAscii(cc) = *self;
41494159
cc == c
41504160
}

0 commit comments

Comments
 (0)