Improved std::ascii
- Fixed tests - Added methods - Renamed casting methods to be shorter closes #7150
This commit is contained in:
@@ -61,7 +61,7 @@ pub use path::Path;
|
|||||||
pub use path::PosixPath;
|
pub use path::PosixPath;
|
||||||
pub use path::WindowsPath;
|
pub use path::WindowsPath;
|
||||||
pub use ptr::RawPtr;
|
pub use ptr::RawPtr;
|
||||||
pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr};
|
pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr, ToBytesConsume};
|
||||||
pub use str::{Str, StrVector, StrSlice, OwnedStr, StrUtil, NullTerminatedStr};
|
pub use str::{Str, StrVector, StrSlice, OwnedStr, StrUtil, NullTerminatedStr};
|
||||||
pub use from_str::{FromStr};
|
pub use from_str::{FromStr};
|
||||||
pub use to_bytes::IterBytes;
|
pub use to_bytes::IterBytes;
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ use cast;
|
|||||||
use old_iter::BaseIter;
|
use old_iter::BaseIter;
|
||||||
use iterator::IteratorUtil;
|
use iterator::IteratorUtil;
|
||||||
use vec::{CopyableVector, ImmutableVector, OwnedVector};
|
use vec::{CopyableVector, ImmutableVector, OwnedVector};
|
||||||
|
use to_bytes::IterBytes;
|
||||||
|
|
||||||
/// Datatype to hold one ascii character. It is 8 bit long.
|
/// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct Ascii { priv chr: u8 }
|
pub struct Ascii { priv chr: u8 }
|
||||||
|
|
||||||
@@ -72,6 +73,9 @@ pub trait AsciiCast<T> {
|
|||||||
/// Convert to an ascii type
|
/// Convert to an ascii type
|
||||||
fn to_ascii(&self) -> T;
|
fn to_ascii(&self) -> T;
|
||||||
|
|
||||||
|
/// Convert to an ascii type, not doing any range asserts
|
||||||
|
unsafe fn to_ascii_nocheck(&self) -> T;
|
||||||
|
|
||||||
/// Check if convertible to ascii
|
/// Check if convertible to ascii
|
||||||
fn is_ascii(&self) -> bool;
|
fn is_ascii(&self) -> bool;
|
||||||
}
|
}
|
||||||
@@ -80,7 +84,12 @@ impl<'self> AsciiCast<&'self[Ascii]> for &'self [u8] {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_ascii(&self) -> &'self[Ascii] {
|
fn to_ascii(&self) -> &'self[Ascii] {
|
||||||
assert!(self.is_ascii());
|
assert!(self.is_ascii());
|
||||||
unsafe{ cast::transmute(*self) }
|
unsafe {self.to_ascii_nocheck()}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
unsafe fn to_ascii_nocheck(&self) -> &'self[Ascii] {
|
||||||
|
cast::transmute(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -96,8 +105,13 @@ impl<'self> AsciiCast<&'self[Ascii]> for &'self str {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_ascii(&self) -> &'self[Ascii] {
|
fn to_ascii(&self) -> &'self[Ascii] {
|
||||||
assert!(self.is_ascii());
|
assert!(self.is_ascii());
|
||||||
let (p,len): (*u8, uint) = unsafe{ cast::transmute(*self) };
|
unsafe {self.to_ascii_nocheck()}
|
||||||
unsafe{ cast::transmute((p, len - 1))}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
unsafe fn to_ascii_nocheck(&self) -> &'self[Ascii] {
|
||||||
|
let (p,len): (*u8, uint) = cast::transmute(*self);
|
||||||
|
cast::transmute((p, len - 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -110,6 +124,11 @@ impl AsciiCast<Ascii> for u8 {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_ascii(&self) -> Ascii {
|
fn to_ascii(&self) -> Ascii {
|
||||||
assert!(self.is_ascii());
|
assert!(self.is_ascii());
|
||||||
|
unsafe {self.to_ascii_nocheck()}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
unsafe fn to_ascii_nocheck(&self) -> Ascii {
|
||||||
Ascii{ chr: *self }
|
Ascii{ chr: *self }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,6 +142,11 @@ impl AsciiCast<Ascii> for char {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_ascii(&self) -> Ascii {
|
fn to_ascii(&self) -> Ascii {
|
||||||
assert!(self.is_ascii());
|
assert!(self.is_ascii());
|
||||||
|
unsafe {self.to_ascii_nocheck()}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
unsafe fn to_ascii_nocheck(&self) -> Ascii {
|
||||||
Ascii{ chr: *self as u8 }
|
Ascii{ chr: *self as u8 }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,26 +159,38 @@ impl AsciiCast<Ascii> for char {
|
|||||||
/// Trait for copyless casting to an ascii vector.
|
/// Trait for copyless casting to an ascii vector.
|
||||||
pub trait OwnedAsciiCast {
|
pub trait OwnedAsciiCast {
|
||||||
/// Take ownership and cast to an ascii vector without trailing zero element.
|
/// Take ownership and cast to an ascii vector without trailing zero element.
|
||||||
fn to_ascii_consume(self) -> ~[Ascii];
|
fn into_ascii(self) -> ~[Ascii];
|
||||||
|
|
||||||
|
/// Take ownership and cast to an ascii vector without trailing zero element.
|
||||||
|
/// Does not perform validation checks.
|
||||||
|
unsafe fn into_ascii_nocheck(self) -> ~[Ascii];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OwnedAsciiCast for ~[u8] {
|
impl OwnedAsciiCast for ~[u8] {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_ascii_consume(self) -> ~[Ascii] {
|
fn into_ascii(self) -> ~[Ascii] {
|
||||||
assert!(self.is_ascii());
|
assert!(self.is_ascii());
|
||||||
unsafe {cast::transmute(self)}
|
unsafe {self.into_ascii_nocheck()}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
unsafe fn into_ascii_nocheck(self) -> ~[Ascii] {
|
||||||
|
cast::transmute(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OwnedAsciiCast for ~str {
|
impl OwnedAsciiCast for ~str {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_ascii_consume(self) -> ~[Ascii] {
|
fn into_ascii(self) -> ~[Ascii] {
|
||||||
assert!(self.is_ascii());
|
assert!(self.is_ascii());
|
||||||
let mut s = self;
|
unsafe {self.into_ascii_nocheck()}
|
||||||
unsafe {
|
}
|
||||||
str::raw::pop_byte(&mut s);
|
|
||||||
cast::transmute(s)
|
#[inline(always)]
|
||||||
}
|
unsafe fn into_ascii_nocheck(self) -> ~[Ascii] {
|
||||||
|
let mut r: ~[Ascii] = cast::transmute(self);
|
||||||
|
r.pop();
|
||||||
|
r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +205,8 @@ pub trait AsciiStr {
|
|||||||
/// Convert to vector representing a upper cased ascii string.
|
/// Convert to vector representing a upper cased ascii string.
|
||||||
fn to_upper(&self) -> ~[Ascii];
|
fn to_upper(&self) -> ~[Ascii];
|
||||||
|
|
||||||
|
/// Compares two Ascii strings ignoring case
|
||||||
|
fn eq_ignore_case(self, other: &[Ascii]) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'self> AsciiStr for &'self [Ascii] {
|
impl<'self> AsciiStr for &'self [Ascii] {
|
||||||
@@ -188,20 +226,45 @@ impl<'self> AsciiStr for &'self [Ascii] {
|
|||||||
fn to_upper(&self) -> ~[Ascii] {
|
fn to_upper(&self) -> ~[Ascii] {
|
||||||
self.map(|a| a.to_upper())
|
self.map(|a| a.to_upper())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn eq_ignore_case(self, other: &[Ascii]) -> bool {
|
||||||
|
do self.iter().zip(other.iter()).all |(&a, &b)| { a.eq_ignore_case(b) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToStrConsume for ~[Ascii] {
|
impl ToStrConsume for ~[Ascii] {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_str_consume(self) -> ~str {
|
fn into_str(self) -> ~str {
|
||||||
let mut cpy = self;
|
let mut cpy = self;
|
||||||
cpy.push(0u8.to_ascii());
|
cpy.push(0u8.to_ascii());
|
||||||
unsafe {cast::transmute(cpy)}
|
unsafe {cast::transmute(cpy)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IterBytes for Ascii {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_bytes(&self, _lsb0: bool, f: &fn(buf: &[u8]) -> bool) -> bool {
|
||||||
|
f([self.to_byte()])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Trait to convert to a owned byte array by consuming self
|
||||||
|
pub trait ToBytesConsume {
|
||||||
|
/// Converts to a owned byte array by consuming self
|
||||||
|
fn into_bytes(self) -> ~[u8];
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToBytesConsume for ~[Ascii] {
|
||||||
|
fn into_bytes(self) -> ~[u8] {
|
||||||
|
unsafe {cast::transmute(self)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use to_bytes::ToBytes;
|
||||||
|
|
||||||
macro_rules! v2ascii (
|
macro_rules! v2ascii (
|
||||||
( [$($e:expr),*]) => ( [$(Ascii{chr:$e}),*]);
|
( [$($e:expr),*]) => ( [$(Ascii{chr:$e}),*]);
|
||||||
@@ -245,6 +308,8 @@ mod tests {
|
|||||||
assert_eq!("YMCA".to_ascii().to_lower().to_str_ascii(), ~"ymca");
|
assert_eq!("YMCA".to_ascii().to_lower().to_str_ascii(), ~"ymca");
|
||||||
assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().to_str_ascii(), ~"ABCDEFXYZ:.;");
|
assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().to_str_ascii(), ~"ABCDEFXYZ:.;");
|
||||||
|
|
||||||
|
assert!("aBcDeF&?#".to_ascii().eq_ignore_case("AbCdEf&?#".to_ascii()));
|
||||||
|
|
||||||
assert!("".is_ascii());
|
assert!("".is_ascii());
|
||||||
assert!("a".is_ascii());
|
assert!("a".is_ascii());
|
||||||
assert!(!"\u2009".is_ascii());
|
assert!(!"\u2009".is_ascii());
|
||||||
@@ -253,21 +318,22 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_owned_ascii_vec() {
|
fn test_owned_ascii_vec() {
|
||||||
// FIXME: #4318 Compiler crashes on moving self
|
assert_eq!((~"( ;").into_ascii(), v2ascii!(~[40, 32, 59]));
|
||||||
//assert_eq!(~"( ;".to_ascii_consume(), v2ascii!(~[40, 32, 59]));
|
assert_eq!((~[40u8, 32u8, 59u8]).into_ascii(), v2ascii!(~[40, 32, 59]));
|
||||||
//assert_eq!(~[40u8, 32u8, 59u8].to_ascii_consume(), v2ascii!(~[40, 32, 59]));
|
|
||||||
//assert_eq!(~"( ;".to_ascii_consume_with_null(), v2ascii!(~[40, 32, 59, 0]));
|
|
||||||
//assert_eq!(~[40u8, 32u8, 59u8].to_ascii_consume_with_null(),
|
|
||||||
// v2ascii!(~[40, 32, 59, 0]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ascii_to_str() { assert_eq!(v2ascii!([40, 32, 59]).to_str_ascii(), ~"( ;"); }
|
fn test_ascii_to_str() { assert_eq!(v2ascii!([40, 32, 59]).to_str_ascii(), ~"( ;"); }
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ascii_to_str_consume() {
|
fn test_ascii_into_str() {
|
||||||
// FIXME: #4318 Compiler crashes on moving self
|
assert_eq!(v2ascii!(~[40, 32, 59]).into_str(), ~"( ;");
|
||||||
//assert_eq!(v2ascii!(~[40, 32, 59]).to_str_consume(), ~"( ;");
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ascii_to_bytes() {
|
||||||
|
assert_eq!(v2ascii!(~[40, 32, 59]).to_bytes(false), ~[40u8, 32u8, 59u8]);
|
||||||
|
assert_eq!(v2ascii!(~[40, 32, 59]).into_bytes(), ~[40u8, 32u8, 59u8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] #[should_fail]
|
#[test] #[should_fail]
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ pub trait ToStr {
|
|||||||
/// Trait for converting a type to a string, consuming it in the process.
|
/// Trait for converting a type to a string, consuming it in the process.
|
||||||
pub trait ToStrConsume {
|
pub trait ToStrConsume {
|
||||||
/// Cosume and convert to a string.
|
/// Cosume and convert to a string.
|
||||||
fn to_str_consume(self) -> ~str;
|
fn into_str(self) -> ~str;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToStr for () {
|
impl ToStr for () {
|
||||||
|
|||||||
Reference in New Issue
Block a user