@@ -1355,6 +1355,7 @@ pub mod raw {
1355
1355
use libc;
1356
1356
use ptr;
1357
1357
use ptr:: RawPtr ;
1358
+ use option:: { Option , Some , None } ;
1358
1359
use str:: { is_utf8, OwnedStr , StrSlice } ;
1359
1360
use vec;
1360
1361
use vec:: { MutableVector , ImmutableVector , OwnedVector } ;
@@ -1464,23 +1465,31 @@ pub mod raw {
1464
1465
}
1465
1466
1466
1467
/// Removes the last byte from a string and returns it.
1468
+ /// Returns None when an empty string is passed.
1467
1469
/// The caller must preserve the valid UTF-8 property.
1468
- pub unsafe fn pop_byte ( s : & mut ~str ) -> u8 {
1470
+ pub unsafe fn pop_byte ( s : & mut ~str ) -> Option < u8 > {
1469
1471
let len = s. len ( ) ;
1470
- assert ! ( ( len > 0 u) ) ;
1471
- let b = s[ len - 1 u] ;
1472
- s. set_len ( len - 1 ) ;
1473
- return b;
1472
+ if len == 0 u {
1473
+ return None ;
1474
+ } else {
1475
+ let b = s[ len - 1 u] ;
1476
+ s. set_len ( len - 1 ) ;
1477
+ return Some ( b) ;
1478
+ }
1474
1479
}
1475
1480
1476
1481
/// Removes the first byte from a string and returns it.
1482
+ /// Returns None when an empty string is passed.
1477
1483
/// The caller must preserve the valid UTF-8 property.
1478
- pub unsafe fn shift_byte ( s : & mut ~str ) -> u8 {
1484
+ pub unsafe fn shift_byte ( s : & mut ~str ) -> Option < u8 > {
1479
1485
let len = s. len ( ) ;
1480
- assert ! ( ( len > 0 u) ) ;
1481
- let b = s[ 0 ] ;
1482
- * s = s. slice ( 1 , len) . to_owned ( ) ;
1483
- return b;
1486
+ if len == 0 u {
1487
+ return None ;
1488
+ } else {
1489
+ let b = s[ 0 ] ;
1490
+ * s = s. slice ( 1 , len) . to_owned ( ) ;
1491
+ return Some ( b) ;
1492
+ }
1484
1493
}
1485
1494
1486
1495
/// Access the str in its vector representation.
@@ -2273,25 +2282,22 @@ pub trait StrSlice<'a> {
2273
2282
/// Retrieves the first character from a string slice and returns
2274
2283
/// it. This does not allocate a new string; instead, it returns a
2275
2284
/// slice that point one character beyond the character that was
2276
- /// shifted.
2277
- ///
2278
- /// # Failure
2279
- ///
2280
- /// If the string does not contain any characters.
2285
+ /// shifted. If the string does not contain any characters,
2286
+ /// a tuple of None and an empty string is returned instead.
2281
2287
///
2282
2288
/// # Example
2283
2289
///
2284
2290
/// ```rust
2285
2291
/// let s = "Löwe 老虎 Léopard";
2286
2292
/// let (c, s1) = s.slice_shift_char();
2287
- /// assert_eq!(c, 'L');
2293
+ /// assert_eq!(c, Some( 'L') );
2288
2294
/// assert_eq!(s1, "öwe 老虎 Léopard");
2289
2295
///
2290
2296
/// let (c, s2) = s1.slice_shift_char();
2291
- /// assert_eq!(c, 'ö');
2297
+ /// assert_eq!(c, Some( 'ö') );
2292
2298
/// assert_eq!(s2, "we 老虎 Léopard");
2293
2299
/// ```
2294
- fn slice_shift_char( & self ) -> ( char , & ' a str ) ;
2300
+ fn slice_shift_char( & self ) -> ( Option < char > , & ' a str ) ;
2295
2301
2296
2302
/// Levenshtein Distance between two strings.
2297
2303
fn lev_distance( & self , t: & str ) -> uint;
@@ -2744,10 +2750,14 @@ impl<'a> StrSlice<'a> for &'a str {
2744
2750
}
2745
2751
2746
2752
#[ inline]
2747
- fn slice_shift_char( & self ) -> ( char , & ' a str ) {
2748
- let CharRange { ch, next} = self . char_range_at( 0 u) ;
2749
- let next_s = unsafe { raw:: slice_bytes( * self , next, self . len( ) ) } ;
2750
- return ( ch, next_s) ;
2753
+ fn slice_shift_char( & self ) -> ( Option <char >, & ' a str ) {
2754
+ if self . is_empty( ) {
2755
+ return ( None , * self ) ;
2756
+ } else {
2757
+ let CharRange { ch, next} = self . char_range_at( 0 u) ;
2758
+ let next_s = unsafe { raw:: slice_bytes( * self , next, self . len( ) ) } ;
2759
+ return ( Some ( ch) , next_s) ;
2760
+ }
2751
2761
}
2752
2762
2753
2763
fn lev_distance( & self , t: & str ) -> uint {
@@ -2810,19 +2820,13 @@ pub trait OwnedStr {
2810
2820
/// Appends a character to the back of a string
2811
2821
fn push_char( & mut self , c: char ) ;
2812
2822
2813
- /// Remove the final character from a string and return it
2814
- ///
2815
- /// # Failure
2816
- ///
2817
- /// If the string does not contain any characters
2818
- fn pop_char( & mut self ) -> char ;
2823
+ /// Remove the final character from a string and return it. Return None
2824
+ /// when the string is empty.
2825
+ fn pop_char( & mut self ) -> Option <char >;
2819
2826
2820
- /// Remove the first character from a string and return it
2821
- ///
2822
- /// # Failure
2823
- ///
2824
- /// If the string does not contain any characters
2825
- fn shift_char( & mut self ) -> char ;
2827
+ /// Remove the first character from a string and return it. Return None
2828
+ /// when the string is empty.
2829
+ fn shift_char( & mut self ) -> Option <char >;
2826
2830
2827
2831
/// Prepend a char to a string
2828
2832
fn unshift_char( & mut self , ch: char ) ;
@@ -2925,19 +2929,26 @@ impl OwnedStr for ~str {
2925
2929
}
2926
2930
2927
2931
#[ inline]
2928
- fn pop_char( & mut self ) -> char {
2932
+ fn pop_char( & mut self ) -> Option < char > {
2929
2933
let end = self . len( ) ;
2930
- assert!( end > 0 u) ;
2931
- let CharRange { ch, next} = self . char_range_at_reverse( end) ;
2932
- unsafe { self . set_len( next) ; }
2933
- return ch;
2934
+ if end == 0 u {
2935
+ return None ;
2936
+ } else {
2937
+ let CharRange { ch, next} = self . char_range_at_reverse( end) ;
2938
+ unsafe { self . set_len( next) ; }
2939
+ return Some ( ch) ;
2940
+ }
2934
2941
}
2935
2942
2936
2943
#[ inline]
2937
- fn shift_char( & mut self ) -> char {
2938
- let CharRange { ch, next} = self . char_range_at( 0 u) ;
2939
- * self = self . slice( next, self . len( ) ) . to_owned( ) ;
2940
- return ch;
2944
+ fn shift_char( & mut self ) -> Option <char > {
2945
+ if self . is_empty( ) {
2946
+ return None ;
2947
+ } else {
2948
+ let CharRange { ch, next} = self . char_range_at( 0 u) ;
2949
+ * self = self . slice( next, self . len( ) ) . to_owned( ) ;
2950
+ return Some ( ch) ;
2951
+ }
2941
2952
}
2942
2953
2943
2954
#[ inline]
@@ -3148,22 +3159,23 @@ mod tests {
3148
3159
let mut data = ~"ประเทศไทย中华";
3149
3160
let cc = data.pop_char();
3150
3161
assert_eq!(~" ประเทศไทย中", data);
3151
- assert_eq!('华', cc);
3162
+ assert_eq!(Some( '华') , cc);
3152
3163
}
3153
3164
3154
3165
#[test]
3155
3166
fn test_pop_char_2() {
3156
3167
let mut data2 = ~" 华";
3157
3168
let cc2 = data2.pop_char();
3158
3169
assert_eq!(~" ", data2);
3159
- assert_eq!('华', cc2);
3170
+ assert_eq!(Some( '华') , cc2);
3160
3171
}
3161
3172
3162
3173
#[test]
3163
- #[should_fail]
3164
- fn test_pop_char_fail() {
3174
+ fn test_pop_char_empty() {
3165
3175
let mut data = ~" ";
3166
- let _cc3 = data.pop_char();
3176
+ let cc3 = data.pop_char();
3177
+ assert_eq!(~" ", data);
3178
+ assert_eq!(None, cc3);
3167
3179
}
3168
3180
3169
3181
#[test]
@@ -3182,7 +3194,7 @@ mod tests {
3182
3194
let mut data = ~" ประเทศไทย中";
3183
3195
let cc = data.shift_char();
3184
3196
assert_eq!(~" ระเทศไทย中", data);
3185
- assert_eq!('ป', cc);
3197
+ assert_eq!(Some( 'ป') , cc);
3186
3198
}
3187
3199
3188
3200
#[test]
@@ -3599,6 +3611,18 @@ mod tests {
3599
3611
assert!( !" _ " . is_whitespace( ) ) ;
3600
3612
}
3601
3613
3614
+ #[ test]
3615
+ fn test_slice_shift_char( ) {
3616
+ let data = "ประเทศไทย中" ;
3617
+ assert_eq!( data. slice_shift_char( ) , ( Some ( 'ป' ) , "ระเทศไทย中" ) ) ;
3618
+ }
3619
+
3620
+ #[ test]
3621
+ fn test_slice_shift_char_2( ) {
3622
+ let empty = "" ;
3623
+ assert_eq!( empty. slice_shift_char( ) , ( None , "" ) ) ;
3624
+ }
3625
+
3602
3626
#[ test]
3603
3627
fn test_push_byte( ) {
3604
3628
let mut s = ~"ABC ";
@@ -3611,15 +3635,15 @@ mod tests {
3611
3635
let mut s = ~" ABC ";
3612
3636
let b = unsafe{raw::shift_byte(&mut s)};
3613
3637
assert_eq!(s, ~" BC ");
3614
- assert_eq!(b, 65u8);
3638
+ assert_eq!(b, Some( 65u8) );
3615
3639
}
3616
3640
3617
3641
#[test]
3618
3642
fn test_pop_byte() {
3619
3643
let mut s = ~" ABC ";
3620
3644
let b = unsafe{raw::pop_byte(&mut s)};
3621
3645
assert_eq!(s, ~" AB ");
3622
- assert_eq!(b, 67u8);
3646
+ assert_eq!(b, Some( 67u8) );
3623
3647
}
3624
3648
3625
3649
#[test]
0 commit comments