@@ -255,6 +255,17 @@ impl CharEq for extern "Rust" fn(char) -> bool {
255255 fn only_ascii ( & self ) -> bool { false }
256256}
257257
258+ impl < ' self , C : CharEq > CharEq for & ' self [ C ] {
259+ #[ inline( always) ]
260+ fn matches ( & self , c : char ) -> bool {
261+ self . iter ( ) . any ( |m| m. matches ( c) )
262+ }
263+
264+ fn only_ascii ( & self ) -> bool {
265+ self . iter ( ) . all ( |m| m. only_ascii ( ) )
266+ }
267+ }
268+
258269
259270/// An iterator over the substrings of a string, separated by `sep`.
260271pub struct StrCharSplitIterator < ' self , Sep > {
@@ -1249,9 +1260,9 @@ pub trait StrSlice<'self> {
12491260 fn trim(&self) -> &'self str;
12501261 fn trim_left(&self) -> &'self str;
12511262 fn trim_right(&self) -> &'self str;
1252- fn trim_chars(&self, chars_to_trim : &[char] ) -> &'self str;
1253- fn trim_left_chars(&self, chars_to_trim : &[char] ) -> &'self str;
1254- fn trim_right_chars(&self, chars_to_trim : &[char] ) -> &'self str;
1263+ fn trim_chars<C: CharEq> (&self, to_trim : &C ) -> &'self str;
1264+ fn trim_left_chars<C: CharEq> (&self, to_trim : &C ) -> &'self str;
1265+ fn trim_right_chars<C: CharEq> (&self, to_trim : &C ) -> &'self str;
12551266 fn replace(&self, from: &str, to: &str) -> ~str;
12561267 fn to_owned(&self) -> ~str;
12571268 fn to_managed(&self) -> @str;
@@ -1542,49 +1553,51 @@ impl<'self> StrSlice<'self> for &'self str {
15421553 /// Returns a string with leading whitespace removed
15431554 #[inline]
15441555 fn trim_left(&self) -> &'self str {
1545- match self.find(|c| !char::is_whitespace(c)) {
1546- None => " ",
1547- Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) }
1548- }
1556+ self.trim_left_chars(&char::is_whitespace)
15491557 }
15501558 /// Returns a string with trailing whitespace removed
15511559 #[inline]
15521560 fn trim_right(&self) -> &'self str {
1553- match self.rfind(|c| !char::is_whitespace(c)) {
1554- None => " ",
1555- Some(last) => {
1556- let next = self.char_range_at(last).next;
1557- unsafe { raw::slice_bytes(*self, 0u, next) }
1558- }
1559- }
1561+ self.trim_right_chars(&char::is_whitespace)
15601562 }
15611563
15621564 /**
1563- * Returns a string with leading and trailing `chars_to_trim ` removed.
1565+ * Returns a string with characters that match `to_trim ` removed.
15641566 *
15651567 * # Arguments
15661568 *
1567- * * chars_to_trim - A vector of chars
1569+ * * to_trim - a character matcher
1570+ *
1571+ * # Example
15681572 *
1573+ * ~~~
1574+ * assert_eq!(" 11 foo1bar11".trim_chars(&'1'), " foo1bar")
1575+ * assert_eq!(" 12 foo1bar12".trim_chars(& &['1', '2']), " foo1bar")
1576+ * assert_eq!(" 123 foo1bar123".trim_chars(&|c: char| c.is_digit()), " foo1bar")
1577+ * ~~~
15691578 */
15701579 #[inline]
1571- fn trim_chars(&self, chars_to_trim : &[char] ) -> &'self str {
1572- self.trim_left_chars(chars_to_trim ).trim_right_chars(chars_to_trim )
1580+ fn trim_chars<C: CharEq> (&self, to_trim : &C ) -> &'self str {
1581+ self.trim_left_chars(to_trim ).trim_right_chars(to_trim )
15731582 }
15741583 /**
15751584 * Returns a string with leading `chars_to_trim` removed.
15761585 *
15771586 * # Arguments
15781587 *
1579- * * s - A string
1580- * * chars_to_trim - A vector of chars
1588+ * * to_trim - a character matcher
1589+ *
1590+ * # Example
15811591 *
1592+ * ~~~
1593+ * assert_eq!(" 11 foo1bar11".trim_left_chars(&'1'), " foo1bar11")
1594+ * assert_eq!(" 12 foo1bar12".trim_left_chars(& &['1', '2']), " foo1bar12")
1595+ * assert_eq!(" 123 foo1bar123".trim_left_chars(&|c: char| c.is_digit()), " foo1bar123")
1596+ * ~~~
15821597 */
15831598 #[inline]
1584- fn trim_left_chars(&self, chars_to_trim: &[char]) -> &'self str {
1585- if chars_to_trim.is_empty() { return *self; }
1586-
1587- match self.find(|c| !chars_to_trim.contains(&c)) {
1599+ fn trim_left_chars<C: CharEq>(&self, to_trim: &C) -> &'self str {
1600+ match self.find(|c: char| !to_trim.matches(c)) {
15881601 None => " ",
15891602 Some(first) => unsafe { raw::slice_bytes(*self, first, self.len()) }
15901603 }
@@ -1594,15 +1607,19 @@ impl<'self> StrSlice<'self> for &'self str {
15941607 *
15951608 * # Arguments
15961609 *
1597- * * s - A string
1598- * * chars_to_trim - A vector of chars
1610+ * * to_trim - a character matcher
1611+ *
1612+ * # Example
15991613 *
1614+ * ~~~
1615+ * assert_eq!(" 11 foo1bar11".trim_right_chars(&'1'), " 11 foo1bar")
1616+ * assert_eq!(" 12 foo1bar12".trim_right_chars(& &['1', '2']), " 12 foo1bar")
1617+ * assert_eq!(" 123 foo1bar123".trim_right_chars(&|c: char| c.is_digit()), " 123 foo1bar")
1618+ * ~~~
16001619 */
16011620 #[inline]
1602- fn trim_right_chars(&self, chars_to_trim: &[char]) -> &'self str {
1603- if chars_to_trim.is_empty() { return *self; }
1604-
1605- match self.rfind(|c| !chars_to_trim.contains(&c)) {
1621+ fn trim_right_chars<C: CharEq>(&self, to_trim: &C) -> &'self str {
1622+ match self.rfind(|c: char| !to_trim.matches(c)) {
16061623 None => " ",
16071624 Some(last) => {
16081625 let next = self.char_range_at(last).next;
@@ -2661,26 +2678,41 @@ mod tests {
26612678
26622679 #[ test]
26632680 fn test_trim_left_chars( ) {
2664- assert_eq!( " *** foo *** " . trim_left_chars( [ ] ) , " *** foo *** " ) ;
2665- assert_eq!( " *** foo *** " . trim_left_chars( [ '*' , ' ' ] ) , "foo *** " ) ;
2666- assert_eq!( " *** *** " . trim_left_chars( [ '*' , ' ' ] ) , "" ) ;
2667- assert_eq!( "foo *** " . trim_left_chars( [ '*' , ' ' ] ) , "foo *** " ) ;
2681+ let v: & [ char ] = & [ ] ;
2682+ assert_eq!( " *** foo *** " . trim_left_chars( & v) , " *** foo *** " ) ;
2683+ assert_eq!( " *** foo *** " . trim_left_chars( & & [ '*' , ' ' ] ) , "foo *** " ) ;
2684+ assert_eq!( " *** *** " . trim_left_chars( & & [ '*' , ' ' ] ) , "" ) ;
2685+ assert_eq!( "foo *** " . trim_left_chars( & & [ '*' , ' ' ] ) , "foo *** " ) ;
2686+
2687+ assert_eq!( "11foo1bar11" . trim_left_chars( & '1' ) , "foo1bar11" ) ;
2688+ assert_eq!( "12foo1bar12" . trim_left_chars( & & [ '1' , '2' ] ) , "foo1bar12" ) ;
2689+ assert_eq!( "123foo1bar123" . trim_left_chars( & |c: char | c. is_digit( ) ) , "foo1bar123" ) ;
26682690 }
26692691
26702692 #[ test]
26712693 fn test_trim_right_chars( ) {
2672- assert_eq!( " *** foo *** " . trim_right_chars( [ ] ) , " *** foo *** " ) ;
2673- assert_eq!( " *** foo *** " . trim_right_chars( [ '*' , ' ' ] ) , " *** foo" ) ;
2674- assert_eq!( " *** *** " . trim_right_chars( [ '*' , ' ' ] ) , "" ) ;
2675- assert_eq!( " *** foo" . trim_right_chars( [ '*' , ' ' ] ) , " *** foo" ) ;
2694+ let v: & [ char ] = & [ ] ;
2695+ assert_eq!( " *** foo *** " . trim_right_chars( & v) , " *** foo *** " ) ;
2696+ assert_eq!( " *** foo *** " . trim_right_chars( & & [ '*' , ' ' ] ) , " *** foo" ) ;
2697+ assert_eq!( " *** *** " . trim_right_chars( & & [ '*' , ' ' ] ) , "" ) ;
2698+ assert_eq!( " *** foo" . trim_right_chars( & & [ '*' , ' ' ] ) , " *** foo" ) ;
2699+
2700+ assert_eq!( "11foo1bar11" . trim_right_chars( & '1' ) , "11foo1bar" ) ;
2701+ assert_eq!( "12foo1bar12" . trim_right_chars( & & [ '1' , '2' ] ) , "12foo1bar" ) ;
2702+ assert_eq!( "123foo1bar123" . trim_right_chars( & |c: char | c. is_digit( ) ) , "123foo1bar" ) ;
26762703 }
26772704
26782705 #[ test]
26792706 fn test_trim_chars( ) {
2680- assert_eq!( " *** foo *** " . trim_chars( [ ] ) , " *** foo *** " ) ;
2681- assert_eq!( " *** foo *** " . trim_chars( [ '*' , ' ' ] ) , "foo" ) ;
2682- assert_eq!( " *** *** " . trim_chars( [ '*' , ' ' ] ) , "" ) ;
2683- assert_eq!( "foo" . trim_chars( [ '*' , ' ' ] ) , "foo" ) ;
2707+ let v: & [ char ] = & [ ] ;
2708+ assert_eq!( " *** foo *** " . trim_chars( & v) , " *** foo *** " ) ;
2709+ assert_eq!( " *** foo *** " . trim_chars( & & [ '*' , ' ' ] ) , "foo" ) ;
2710+ assert_eq!( " *** *** " . trim_chars( & & [ '*' , ' ' ] ) , "" ) ;
2711+ assert_eq!( "foo" . trim_chars( & & [ '*' , ' ' ] ) , "foo" ) ;
2712+
2713+ assert_eq!( "11foo1bar11" . trim_chars( & '1' ) , "foo1bar" ) ;
2714+ assert_eq!( "12foo1bar12" . trim_chars( & & [ '1' , '2' ] ) , "foo1bar" ) ;
2715+ assert_eq!( "123foo1bar123" . trim_chars( & |c: char | c. is_digit( ) ) , "foo1bar" ) ;
26842716 }
26852717
26862718 #[ test]
0 commit comments