@@ -23,7 +23,7 @@ use to_bytes::IterBytes;
2323use option:: { Some , None } ;
2424
2525/// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
26- #[ deriving( Clone , Eq ) ]
26+ #[ deriving( Clone , Eq , Ord , TotalOrd , TotalEq ) ]
2727pub struct Ascii { priv chr: u8 }
2828
2929impl Ascii {
@@ -250,21 +250,40 @@ impl ToBytesConsume for ~[Ascii] {
250250 }
251251}
252252
253-
254- /// Convert the string to ASCII upper case:
255- /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
256- /// but non-ASCII letters are unchanged.
257- #[ inline]
258- pub fn to_ascii_upper ( string : & str ) -> ~str {
259- map_bytes ( string, ASCII_UPPER_MAP )
253+ /// Extension methods for ASCII-subset only operations on strings
254+ pub trait StrAsciiExt {
255+ /// Convert the string to ASCII upper case:
256+ /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
257+ /// but non-ASCII letters are unchanged.
258+ fn to_ascii_upper ( & self ) -> ~str ;
259+
260+ /// Convert the string to ASCII lower case:
261+ /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
262+ /// but non-ASCII letters are unchanged.
263+ fn to_ascii_lower ( & self ) -> ~str ;
264+
265+ /// Check that two strings are an ASCII case-insensitive match.
266+ /// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
267+ /// but without allocating and copying temporary strings.
268+ fn eq_ignore_ascii_case ( & self , other : & str ) -> bool ;
260269}
261270
262- /// Convert the string to ASCII lower case:
263- /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
264- /// but non-ASCII letters are unchanged.
265- #[ inline]
266- pub fn to_ascii_lower ( string : & str ) -> ~str {
267- map_bytes ( string, ASCII_LOWER_MAP )
271+ impl < ' self > StrAsciiExt for & ' self str {
272+ #[ inline]
273+ fn to_ascii_upper ( & self ) -> ~str {
274+ map_bytes ( * self , ASCII_UPPER_MAP )
275+ }
276+
277+ #[ inline]
278+ fn to_ascii_lower ( & self ) -> ~str {
279+ map_bytes ( * self , ASCII_LOWER_MAP )
280+ }
281+
282+ #[ inline]
283+ fn eq_ignore_ascii_case ( & self , other : & str ) -> bool {
284+ self . len ( ) == other. len ( ) && self . as_bytes ( ) . iter ( ) . zip ( other. as_bytes ( ) . iter ( ) ) . all (
285+ |( byte_self, byte_other) | ASCII_LOWER_MAP [ * byte_self] == ASCII_LOWER_MAP [ * byte_other] )
286+ }
268287}
269288
270289#[ inline]
@@ -283,15 +302,6 @@ fn map_bytes(string: &str, map: &'static [u8]) -> ~str {
283302 result
284303}
285304
286- /// Check that two strings are an ASCII case-insensitive match.
287- /// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
288- /// but without allocating and copying temporary strings.
289- #[ inline]
290- pub fn eq_ignore_ascii_case ( a : & str , b : & str ) -> bool {
291- a. len ( ) == b. len ( ) && a. as_bytes ( ) . iter ( ) . zip ( b. as_bytes ( ) . iter ( ) ) . all (
292- |( byte_a, byte_b) | ASCII_LOWER_MAP [ * byte_a] == ASCII_LOWER_MAP [ * byte_b] )
293- }
294-
295305static ASCII_LOWER_MAP : & ' static [ u8 ] = & [
296306 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
297307 0x08 , 0x09 , 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f ,
@@ -453,49 +463,48 @@ mod tests {
453463
454464 #[test]
455465 fn test_to_ascii_upper() {
456- assert_eq!(to_ascii_upper( " url( ) URL ( ) uRl( ) ürl"), ~" URL ( ) URL ( ) URL ( ) üRL");
457- assert_eq!(to_ascii_upper( " hıKß"), ~" HıKß ");
466+ assert_eq!(" url( ) URL ( ) uRl( ) ürl".to_ascii_upper( ), ~" URL ( ) URL ( ) URL ( ) üRL");
467+ assert_eq!(" hıKß".to_ascii_upper( ), ~" HıKß ");
458468
459469 let mut i = 0;
460470 while i <= 500 {
461471 let c = i as char;
462472 let upper = if 'a' <= c && c <= 'z' { c + 'A' - 'a' } else { c };
463- assert_eq!(to_ascii_upper( from_char(i as char)), from_char(upper))
473+ assert_eq!(from_char(i as char).to_ascii_upper( ), from_char(upper))
464474 i += 1;
465475 }
466476 }
467477
468478 #[test]
469479 fn test_to_ascii_lower() {
470- assert_eq!(to_ascii_lower( " url( ) URL ( ) uRl( ) Ürl"), ~" url( ) url( ) url( ) Ürl");
480+ assert_eq!(" url( ) URL ( ) uRl( ) Ürl".to_ascii_lower( ), ~" url( ) url( ) url( ) Ürl");
471481 // Dotted capital I, Kelvin sign, Sharp S.
472- assert_eq!(to_ascii_lower( " HİKß "), ~" hİKß");
482+ assert_eq!(" HİKß ".to_ascii_lower( ), ~" hİKß");
473483
474484 let mut i = 0;
475485 while i <= 500 {
476486 let c = i as char;
477487 let lower = if 'A' <= c && c <= 'Z' { c + 'a' - 'A' } else { c };
478- assert_eq!(to_ascii_lower( from_char(i as char)), from_char(lower))
488+ assert_eq!(from_char(i as char).to_ascii_lower( ), from_char(lower))
479489 i += 1;
480490 }
481491 }
482492
483-
484493 #[test]
485494 fn test_eq_ignore_ascii_case() {
486- assert!(eq_ignore_ascii_case( " url( ) URL ( ) uRl( ) Ürl", " url( ) url( ) url( ) Ürl"));
487- assert!(!eq_ignore_ascii_case( " Ürl", " ürl"));
495+ assert!(" url( ) URL ( ) uRl( ) Ürl".eq_ignore_ascii_case( " url( ) url( ) url( ) Ürl"));
496+ assert!(!" Ürl".eq_ignore_ascii_case( " ürl"));
488497 // Dotted capital I, Kelvin sign, Sharp S.
489- assert!(eq_ignore_ascii_case( " HİKß ", " hİKß"));
490- assert!(!eq_ignore_ascii_case( " İ", " i"));
491- assert!(!eq_ignore_ascii_case( " K", " k"));
492- assert!(!eq_ignore_ascii_case( " ß", " s" ) ) ;
498+ assert!(" HİKß ".eq_ignore_ascii_case( " hİKß"));
499+ assert!(!" İ".eq_ignore_ascii_case( " i"));
500+ assert!(!" K".eq_ignore_ascii_case( " k"));
501+ assert!(!" ß".eq_ignore_ascii_case( " s" ) ) ;
493502
494503 let mut i = 0 ;
495504 while i <= 500 {
496505 let c = i as char ;
497506 let lower = if 'A' <= c && c <= 'Z' { c + 'a' - 'A' } else { c } ;
498- assert!( eq_ignore_ascii_case ( from_char( i as char ) , from_char( lower) ) ) ;
507+ assert!( from_char( i as char ) . eq_ignore_ascii_case ( from_char( lower) ) ) ;
499508 i += 1 ;
500509 }
501510 }
0 commit comments