Skip to content

Commit 2e98a93

Browse files
committed
auto merge of #10828 : SimonSapin/rust/ascii_opt, r=pcwalton
… instead of failing. Make them default methods on the trait, and also make .to_ascii() a default method while we’re at it.
2 parents 0df9b85 + f8cc9a9 commit 2e98a93

File tree

1 file changed

+70
-36
lines changed

1 file changed

+70
-36
lines changed

src/libstd/ascii.rs

+70-36
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@
1212
1313
use to_str::{ToStr,IntoStr};
1414
use str;
15+
use str::Str;
1516
use str::StrSlice;
1617
use str::OwnedStr;
1718
use container::Container;
1819
use cast;
1920
use iter::Iterator;
20-
use vec::{ImmutableVector, MutableVector};
21+
use vec::{ImmutableVector, MutableVector, Vector};
2122
use to_bytes::IterBytes;
22-
use option::{Some, None};
23+
use option::{Option, Some, None};
2324

2425
/// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
2526
#[deriving(Clone, Eq, Ord, TotalOrd, TotalEq)]
@@ -135,8 +136,22 @@ impl ToStr for Ascii {
135136

136137
/// Trait for converting into an ascii type.
137138
pub trait AsciiCast<T> {
138-
/// Convert to an ascii type
139-
fn to_ascii(&self) -> T;
139+
/// Convert to an ascii type, fail on non-ASCII input.
140+
#[inline]
141+
fn to_ascii(&self) -> T {
142+
assert!(self.is_ascii());
143+
unsafe {self.to_ascii_nocheck()}
144+
}
145+
146+
/// Convert to an ascii type, return None on non-ASCII input.
147+
#[inline]
148+
fn to_ascii_opt(&self) -> Option<T> {
149+
if self.is_ascii() {
150+
Some(unsafe { self.to_ascii_nocheck() })
151+
} else {
152+
None
153+
}
154+
}
140155

141156
/// Convert to an ascii type, not doing any range asserts
142157
unsafe fn to_ascii_nocheck(&self) -> T;
@@ -146,12 +161,6 @@ pub trait AsciiCast<T> {
146161
}
147162

148163
impl<'a> AsciiCast<&'a[Ascii]> for &'a [u8] {
149-
#[inline]
150-
fn to_ascii(&self) -> &'a[Ascii] {
151-
assert!(self.is_ascii());
152-
unsafe {self.to_ascii_nocheck()}
153-
}
154-
155164
#[inline]
156165
unsafe fn to_ascii_nocheck(&self) -> &'a[Ascii] {
157166
cast::transmute(*self)
@@ -167,12 +176,6 @@ impl<'a> AsciiCast<&'a[Ascii]> for &'a [u8] {
167176
}
168177

169178
impl<'a> AsciiCast<&'a [Ascii]> for &'a str {
170-
#[inline]
171-
fn to_ascii(&self) -> &'a [Ascii] {
172-
assert!(self.is_ascii());
173-
unsafe { self.to_ascii_nocheck() }
174-
}
175-
176179
#[inline]
177180
unsafe fn to_ascii_nocheck(&self) -> &'a [Ascii] {
178181
cast::transmute(*self)
@@ -185,12 +188,6 @@ impl<'a> AsciiCast<&'a [Ascii]> for &'a str {
185188
}
186189

187190
impl AsciiCast<Ascii> for u8 {
188-
#[inline]
189-
fn to_ascii(&self) -> Ascii {
190-
assert!(self.is_ascii());
191-
unsafe {self.to_ascii_nocheck()}
192-
}
193-
194191
#[inline]
195192
unsafe fn to_ascii_nocheck(&self) -> Ascii {
196193
Ascii{ chr: *self }
@@ -203,12 +200,6 @@ impl AsciiCast<Ascii> for u8 {
203200
}
204201

205202
impl AsciiCast<Ascii> for char {
206-
#[inline]
207-
fn to_ascii(&self) -> Ascii {
208-
assert!(self.is_ascii());
209-
unsafe {self.to_ascii_nocheck()}
210-
}
211-
212203
#[inline]
213204
unsafe fn to_ascii_nocheck(&self) -> Ascii {
214205
Ascii{ chr: *self as u8 }
@@ -222,8 +213,25 @@ impl AsciiCast<Ascii> for char {
222213

223214
/// Trait for copyless casting to an ascii vector.
224215
pub trait OwnedAsciiCast {
225-
/// Take ownership and cast to an ascii vector.
226-
fn into_ascii(self) -> ~[Ascii];
216+
/// Check if convertible to ascii
217+
fn is_ascii(&self) -> bool;
218+
219+
/// Take ownership and cast to an ascii vector. Fail on non-ASCII input.
220+
#[inline]
221+
fn into_ascii(self) -> ~[Ascii] {
222+
assert!(self.is_ascii());
223+
unsafe {self.into_ascii_nocheck()}
224+
}
225+
226+
/// Take ownership and cast to an ascii vector. Return None on non-ASCII input.
227+
#[inline]
228+
fn into_ascii_opt(self) -> Option<~[Ascii]> {
229+
if self.is_ascii() {
230+
Some(unsafe { self.into_ascii_nocheck() })
231+
} else {
232+
None
233+
}
234+
}
227235

228236
/// Take ownership and cast to an ascii vector.
229237
/// Does not perform validation checks.
@@ -232,9 +240,8 @@ pub trait OwnedAsciiCast {
232240

233241
impl OwnedAsciiCast for ~[u8] {
234242
#[inline]
235-
fn into_ascii(self) -> ~[Ascii] {
236-
assert!(self.is_ascii());
237-
unsafe {self.into_ascii_nocheck()}
243+
fn is_ascii(&self) -> bool {
244+
self.as_slice().is_ascii()
238245
}
239246

240247
#[inline]
@@ -245,9 +252,8 @@ impl OwnedAsciiCast for ~[u8] {
245252

246253
impl OwnedAsciiCast for ~str {
247254
#[inline]
248-
fn into_ascii(self) -> ~[Ascii] {
249-
assert!(self.is_ascii());
250-
unsafe {self.into_ascii_nocheck()}
255+
fn is_ascii(&self) -> bool {
256+
self.as_slice().is_ascii()
251257
}
252258

253259
#[inline]
@@ -475,9 +481,11 @@ mod tests {
475481
use super::*;
476482
use str::from_char;
477483
use char::from_u32;
484+
use option::{Some, None};
478485

479486
macro_rules! v2ascii (
480487
( [$($e:expr),*]) => ( [$(Ascii{chr:$e}),*]);
488+
(&[$($e:expr),*]) => (&[$(Ascii{chr:$e}),*]);
481489
(~[$($e:expr),*]) => (~[$(Ascii{chr:$e}),*]);
482490
)
483491

@@ -569,6 +577,32 @@ mod tests {
569577
#[test] #[should_fail]
570578
fn test_ascii_fail_char_slice() { 'λ'.to_ascii(); }
571579
580+
fn test_opt() {
581+
assert_eq!(65u8.to_ascii_opt(), Some(Ascii { chr: 65u8 }));
582+
assert_eq!(255u8.to_ascii_opt(), None);
583+
584+
assert_eq!('A'.to_ascii_opt(), Some(Ascii { chr: 65u8 }));
585+
assert_eq!('λ'.to_ascii_opt(), None);
586+
587+
assert_eq!("zoä华".to_ascii_opt(), None);
588+
589+
assert_eq!((&[127u8, 128u8, 255u8]).to_ascii_opt(), None);
590+
591+
let v = [40u8, 32u8, 59u8];
592+
assert_eq!(v.to_ascii_opt(), Some(v2ascii!(&[40, 32, 59])));
593+
let v = [127u8, 128u8, 255u8];
594+
assert_eq!(v.to_ascii_opt(), None);
595+
596+
assert_eq!("( ;".to_ascii_opt(), Some(v2ascii!(&[40, 32, 59])));
597+
assert_eq!("zoä华".to_ascii_opt(), None);
598+
599+
assert_eq!((~[40u8, 32u8, 59u8]).into_ascii_opt(), Some(v2ascii!(~[40, 32, 59])));
600+
assert_eq!((~[127u8, 128u8, 255u8]).into_ascii_opt(), None);
601+
602+
assert_eq!((~"( ;").into_ascii_opt(), Some(v2ascii!(~[40, 32, 59])));
603+
assert_eq!((~"zoä华").into_ascii_opt(), None);
604+
}
605+
572606
#[test]
573607
fn test_to_ascii_upper() {
574608
assert_eq!("url()URL()uRl()ürl".to_ascii_upper(), ~"URL()URL()URL()üRL");

0 commit comments

Comments
 (0)