12
12
13
13
use to_str:: { ToStr , IntoStr } ;
14
14
use str;
15
+ use str:: Str ;
15
16
use str:: StrSlice ;
16
17
use str:: OwnedStr ;
17
18
use container:: Container ;
18
19
use cast;
19
20
use iter:: Iterator ;
20
- use vec:: { ImmutableVector , MutableVector } ;
21
+ use vec:: { ImmutableVector , MutableVector , Vector } ;
21
22
use to_bytes:: IterBytes ;
22
- use option:: { Some , None } ;
23
+ use option:: { Option , Some , None } ;
23
24
24
25
/// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
25
26
#[ deriving( Clone , Eq , Ord , TotalOrd , TotalEq ) ]
@@ -135,8 +136,22 @@ impl ToStr for Ascii {
135
136
136
137
/// Trait for converting into an ascii type.
137
138
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
+ }
140
155
141
156
/// Convert to an ascii type, not doing any range asserts
142
157
unsafe fn to_ascii_nocheck ( & self ) -> T ;
@@ -146,12 +161,6 @@ pub trait AsciiCast<T> {
146
161
}
147
162
148
163
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
-
155
164
#[ inline]
156
165
unsafe fn to_ascii_nocheck ( & self ) -> & ' a [ Ascii ] {
157
166
cast:: transmute ( * self )
@@ -167,12 +176,6 @@ impl<'a> AsciiCast<&'a[Ascii]> for &'a [u8] {
167
176
}
168
177
169
178
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
-
176
179
#[ inline]
177
180
unsafe fn to_ascii_nocheck ( & self ) -> & ' a [ Ascii ] {
178
181
cast:: transmute ( * self )
@@ -185,12 +188,6 @@ impl<'a> AsciiCast<&'a [Ascii]> for &'a str {
185
188
}
186
189
187
190
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
-
194
191
#[ inline]
195
192
unsafe fn to_ascii_nocheck ( & self ) -> Ascii {
196
193
Ascii { chr : * self }
@@ -203,12 +200,6 @@ impl AsciiCast<Ascii> for u8 {
203
200
}
204
201
205
202
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
-
212
203
#[ inline]
213
204
unsafe fn to_ascii_nocheck ( & self ) -> Ascii {
214
205
Ascii { chr : * self as u8 }
@@ -222,8 +213,25 @@ impl AsciiCast<Ascii> for char {
222
213
223
214
/// Trait for copyless casting to an ascii vector.
224
215
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
+ }
227
235
228
236
/// Take ownership and cast to an ascii vector.
229
237
/// Does not perform validation checks.
@@ -232,9 +240,8 @@ pub trait OwnedAsciiCast {
232
240
233
241
impl OwnedAsciiCast for ~[ u8 ] {
234
242
#[ 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 ( )
238
245
}
239
246
240
247
#[ inline]
@@ -245,9 +252,8 @@ impl OwnedAsciiCast for ~[u8] {
245
252
246
253
impl OwnedAsciiCast for ~str {
247
254
#[ 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 ( )
251
257
}
252
258
253
259
#[ inline]
@@ -475,9 +481,11 @@ mod tests {
475
481
use super :: * ;
476
482
use str:: from_char;
477
483
use char:: from_u32;
484
+ use option:: { Some , None } ;
478
485
479
486
macro_rules! v2ascii (
480
487
( [ $( $e: expr) ,* ] ) => ( [ $( Ascii { chr: $e} ) ,* ] ) ;
488
+ ( & [ $( $e: expr) ,* ] ) => ( & [ $( Ascii { chr: $e} ) ,* ] ) ;
481
489
( ~[ $( $e: expr) ,* ] ) => ( ~[ $( Ascii { chr: $e} ) ,* ] ) ;
482
490
)
483
491
@@ -569,6 +577,32 @@ mod tests {
569
577
#[test] #[should_fail]
570
578
fn test_ascii_fail_char_slice() { 'λ'.to_ascii(); }
571
579
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
+
572
606
#[test]
573
607
fn test_to_ascii_upper() {
574
608
assert_eq!(" url( ) URL ( ) uRl( ) ürl".to_ascii_upper(), ~" URL ( ) URL ( ) URL ( ) üRL");
0 commit comments