Skip to content

Commit b86574b

Browse files
committed
Rename the std::ascii::{Owned,}StrAsciiExt traits to {Owned,}AsciiExt
… and implement them on Vec<u8> / &[u8]. [breaking-change]
1 parent ee8365a commit b86574b

File tree

4 files changed

+57
-35
lines changed

4 files changed

+57
-35
lines changed

src/liblog/directive.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::ascii::StrAsciiExt;
11+
use std::ascii::AsciiExt;
1212
use std::cmp;
1313

1414
#[deriving(Show, Clone)]

src/librustc/lint/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#![macro_escape]
3232

3333
use std::hash;
34-
use std::ascii::StrAsciiExt;
34+
use std::ascii::AsciiExt;
3535
use syntax::codemap::Span;
3636
use syntax::visit::FnKind;
3737
use syntax::ast;

src/libstd/ascii.rs

Lines changed: 54 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use iter::Iterator;
2020
use mem;
2121
use option::{Option, Some, None};
2222
use slice::{ImmutableVector, MutableVector, Vector};
23-
use str::{Str, StrAllocating, StrSlice};
23+
use str::{Str, StrSlice};
24+
use str;
2425
use string::String;
2526
use to_string::IntoStr;
2627
use vec::Vec;
@@ -366,91 +367,112 @@ impl IntoBytes for Vec<Ascii> {
366367
}
367368
}
368369

370+
369371
/// Extension methods for ASCII-subset only operations on owned strings
370-
pub trait OwnedStrAsciiExt {
372+
pub trait OwnedAsciiExt {
371373
/// Convert the string to ASCII upper case:
372374
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
373375
/// but non-ASCII letters are unchanged.
374-
fn into_ascii_upper(self) -> String;
376+
fn into_ascii_upper(self) -> Self;
375377

376378
/// Convert the string to ASCII lower case:
377379
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
378380
/// but non-ASCII letters are unchanged.
379-
fn into_ascii_lower(self) -> String;
381+
fn into_ascii_lower(self) -> Self;
380382
}
381383

382384
/// Extension methods for ASCII-subset only operations on string slices
383-
pub trait StrAsciiExt {
385+
pub trait AsciiExt<T> {
384386
/// Makes a copy of the string in ASCII upper case:
385387
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
386388
/// but non-ASCII letters are unchanged.
387-
fn to_ascii_upper(&self) -> String;
389+
fn to_ascii_upper(&self) -> T;
388390

389391
/// Makes a copy of the string in ASCII lower case:
390392
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
391393
/// but non-ASCII letters are unchanged.
392-
fn to_ascii_lower(&self) -> String;
394+
fn to_ascii_lower(&self) -> T;
393395

394396
/// Check that two strings are an ASCII case-insensitive match.
395397
/// Same as `to_ascii_lower(a) == to_ascii_lower(b)`,
396398
/// but without allocating and copying temporary strings.
397-
fn eq_ignore_ascii_case(&self, other: &str) -> bool;
399+
fn eq_ignore_ascii_case(&self, other: Self) -> bool;
398400
}
399401

400-
impl<'a> StrAsciiExt for &'a str {
402+
impl<'a> AsciiExt<String> for &'a str {
401403
#[inline]
402404
fn to_ascii_upper(&self) -> String {
403-
unsafe { str_copy_map_bytes(*self, &ASCII_UPPER_MAP) }
405+
// Vec<u8>::to_ascii_upper() preserves the UTF-8 invariant.
406+
unsafe { str::raw::from_utf8_owned(self.as_bytes().to_ascii_upper()) }
404407
}
405408

406409
#[inline]
407410
fn to_ascii_lower(&self) -> String {
408-
unsafe { str_copy_map_bytes(*self, &ASCII_LOWER_MAP) }
411+
// Vec<u8>::to_ascii_lower() preserves the UTF-8 invariant.
412+
unsafe { str::raw::from_utf8_owned(self.as_bytes().to_ascii_lower()) }
409413
}
410414

411415
#[inline]
412416
fn eq_ignore_ascii_case(&self, other: &str) -> bool {
413-
self.len() == other.len() &&
414-
self.as_bytes().iter().zip(other.as_bytes().iter()).all(
415-
|(byte_self, byte_other)| {
416-
ASCII_LOWER_MAP[*byte_self as uint] ==
417-
ASCII_LOWER_MAP[*byte_other as uint]
418-
})
417+
self.as_bytes().eq_ignore_ascii_case(other.as_bytes())
419418
}
420419
}
421420

422-
impl OwnedStrAsciiExt for String {
421+
impl OwnedAsciiExt for String {
423422
#[inline]
424423
fn into_ascii_upper(self) -> String {
425-
unsafe { str_map_bytes(self, &ASCII_UPPER_MAP) }
424+
// Vec<u8>::into_ascii_upper() preserves the UTF-8 invariant.
425+
unsafe { str::raw::from_utf8_owned(self.into_bytes().into_ascii_upper()) }
426426
}
427427

428428
#[inline]
429429
fn into_ascii_lower(self) -> String {
430-
unsafe { str_map_bytes(self, &ASCII_LOWER_MAP) }
430+
// Vec<u8>::into_ascii_lower() preserves the UTF-8 invariant.
431+
unsafe { str::raw::from_utf8_owned(self.into_bytes().into_ascii_lower()) }
431432
}
432433
}
433434

434-
#[inline]
435-
unsafe fn str_map_bytes(string: String, map: &[u8, ..256]) -> String {
436-
let mut bytes = string.into_bytes();
435+
impl<'a> AsciiExt<Vec<u8>> for &'a [u8] {
436+
#[inline]
437+
fn to_ascii_upper(&self) -> Vec<u8> {
438+
self.iter().map(|&byte| ASCII_UPPER_MAP[byte as uint]).collect()
439+
}
437440

438-
for b in bytes.mut_iter() {
439-
*b = map[*b as uint];
441+
#[inline]
442+
fn to_ascii_lower(&self) -> Vec<u8> {
443+
self.iter().map(|&byte| ASCII_LOWER_MAP[byte as uint]).collect()
440444
}
441445

442-
String::from_utf8(bytes).unwrap()
446+
#[inline]
447+
fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
448+
self.len() == other.len() &&
449+
self.iter().zip(other.iter()).all(
450+
|(byte_self, byte_other)| {
451+
ASCII_LOWER_MAP[*byte_self as uint] ==
452+
ASCII_LOWER_MAP[*byte_other as uint]
453+
})
454+
}
443455
}
444456

445-
#[inline]
446-
unsafe fn str_copy_map_bytes(string: &str, map: &[u8, ..256]) -> String {
447-
let mut s = String::from_str(string);
448-
for b in s.as_mut_bytes().mut_iter() {
449-
*b = map[*b as uint];
457+
impl OwnedAsciiExt for Vec<u8> {
458+
#[inline]
459+
fn into_ascii_upper(mut self) -> Vec<u8> {
460+
for byte in self.mut_iter() {
461+
*byte = ASCII_UPPER_MAP[*byte as uint];
462+
}
463+
self
464+
}
465+
466+
#[inline]
467+
fn into_ascii_lower(mut self) -> Vec<u8> {
468+
for byte in self.mut_iter() {
469+
*byte = ASCII_LOWER_MAP[*byte as uint];
470+
}
471+
self
450472
}
451-
s.into_string()
452473
}
453474

475+
454476
pub static ASCII_LOWER_MAP: [u8, ..256] = [
455477
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
456478
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,

src/test/run-pass/issue-10683.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use std::ascii::StrAsciiExt;
11+
use std::ascii::AsciiExt;
1212

1313
static NAME: &'static str = "hello world";
1414

0 commit comments

Comments
 (0)