@@ -1355,6 +1355,7 @@ pub mod raw {
13551355 use libc;
13561356 use ptr;
13571357 use ptr:: RawPtr ;
1358+ use option:: { Option , Some , None } ;
13581359 use str:: { is_utf8, OwnedStr , StrSlice } ;
13591360 use vec;
13601361 use vec:: { MutableVector , ImmutableVector , OwnedVector } ;
@@ -1465,22 +1466,28 @@ pub mod raw {
14651466
14661467 /// Removes the last byte from a string and returns it.
14671468 /// The caller must preserve the valid UTF-8 property.
1468- pub unsafe fn pop_byte ( s : & mut ~str ) -> u8 {
1469+ pub unsafe fn pop_byte ( s : & mut ~str ) -> Option < u8 > {
14691470 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;
1471+ if len == 0 u {
1472+ return None ;
1473+ } else {
1474+ let b = s[ len - 1 u] ;
1475+ s. set_len ( len - 1 ) ;
1476+ return Some ( b) ;
1477+ }
14741478 }
14751479
14761480 /// Removes the first byte from a string and returns it.
14771481 /// The caller must preserve the valid UTF-8 property.
1478- pub unsafe fn shift_byte ( s : & mut ~str ) -> u8 {
1482+ pub unsafe fn shift_byte ( s : & mut ~str ) -> Option < u8 > {
14791483 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;
1484+ if len == 0 u {
1485+ return None ;
1486+ } else {
1487+ let b = s[ 0 ] ;
1488+ * s = s. slice ( 1 , len) . to_owned ( ) ;
1489+ return Some ( b) ;
1490+ }
14841491 }
14851492
14861493 /// Access the str in its vector representation.
@@ -2291,7 +2298,7 @@ pub trait StrSlice<'a> {
22912298 /// assert_eq!(c, 'ö');
22922299 /// assert_eq!(s2, "we 老虎 Léopard");
22932300 /// ```
2294- fn slice_shift_char( & self ) -> ( char , & ' a str ) ;
2301+ fn slice_shift_char( & self ) -> ( Option < char > , & ' a str ) ;
22952302
22962303 /// Levenshtein Distance between two strings.
22972304 fn lev_distance( & self , t: & str ) -> uint;
@@ -2744,10 +2751,14 @@ impl<'a> StrSlice<'a> for &'a str {
27442751 }
27452752
27462753 #[ 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) ;
2754+ fn slice_shift_char( & self ) -> ( Option <char >, & ' a str ) {
2755+ if self . is_empty( ) {
2756+ return ( None , * self ) ;
2757+ } else {
2758+ let CharRange { ch, next} = self . char_range_at( 0 u) ;
2759+ let next_s = unsafe { raw:: slice_bytes( * self , next, self . len( ) ) } ;
2760+ return ( Some ( ch) , next_s) ;
2761+ }
27512762 }
27522763
27532764 fn lev_distance( & self , t: & str ) -> uint {
@@ -2815,14 +2826,14 @@ pub trait OwnedStr {
28152826 /// # Failure
28162827 ///
28172828 /// If the string does not contain any characters
2818- fn pop_char( & mut self ) -> char ;
2829+ fn pop_char( & mut self ) -> Option < char > ;
28192830
28202831 /// Remove the first character from a string and return it
28212832 ///
28222833 /// # Failure
28232834 ///
28242835 /// If the string does not contain any characters
2825- fn shift_char( & mut self ) -> char ;
2836+ fn shift_char( & mut self ) -> Option < char > ;
28262837
28272838 /// Prepend a char to a string
28282839 fn unshift_char( & mut self , ch: char ) ;
@@ -2925,19 +2936,26 @@ impl OwnedStr for ~str {
29252936 }
29262937
29272938 #[ inline]
2928- fn pop_char( & mut self ) -> char {
2939+ fn pop_char( & mut self ) -> Option < char > {
29292940 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;
2941+ if end == 0 u {
2942+ return None ;
2943+ } else {
2944+ let CharRange { ch, next} = self . char_range_at_reverse( end) ;
2945+ unsafe { self . set_len( next) ; }
2946+ return Some ( ch) ;
2947+ }
29342948 }
29352949
29362950 #[ 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;
2951+ fn shift_char( & mut self ) -> Option <char > {
2952+ if self . is_empty( ) {
2953+ return None ;
2954+ } else {
2955+ let CharRange { ch, next} = self . char_range_at( 0 u) ;
2956+ * self = self . slice( next, self . len( ) ) . to_owned( ) ;
2957+ return Some ( ch) ;
2958+ }
29412959 }
29422960
29432961 #[ inline]
@@ -3148,22 +3166,23 @@ mod tests {
31483166 let mut data = ~"ประเทศไทย中华";
31493167 let cc = data.pop_char();
31503168 assert_eq!(~" ประเทศไทย中", data);
3151- assert_eq!('华', cc);
3169+ assert_eq!(Some( '华') , cc);
31523170 }
31533171
31543172 #[test]
31553173 fn test_pop_char_2() {
31563174 let mut data2 = ~" 华";
31573175 let cc2 = data2.pop_char();
31583176 assert_eq!(~" ", data2);
3159- assert_eq!('华', cc2);
3177+ assert_eq!(Some( '华') , cc2);
31603178 }
31613179
31623180 #[test]
3163- #[should_fail]
3164- fn test_pop_char_fail() {
3181+ fn test_pop_char_empty() {
31653182 let mut data = ~" ";
3166- let _cc3 = data.pop_char();
3183+ let cc3 = data.pop_char();
3184+ assert_eq!(~" ", data);
3185+ assert_eq!(None, cc3);
31673186 }
31683187
31693188 #[test]
@@ -3182,7 +3201,7 @@ mod tests {
31823201 let mut data = ~" ประเทศไทย中";
31833202 let cc = data.shift_char();
31843203 assert_eq!(~" ระเทศไทย中", data);
3185- assert_eq!('ป', cc);
3204+ assert_eq!(Some( 'ป') , cc);
31863205 }
31873206
31883207 #[test]
@@ -3611,15 +3630,15 @@ mod tests {
36113630 let mut s = ~" ABC ";
36123631 let b = unsafe{raw::shift_byte(&mut s)};
36133632 assert_eq!(s, ~" BC ");
3614- assert_eq!(b, 65u8);
3633+ assert_eq!(b, Some( 65u8) );
36153634 }
36163635
36173636 #[test]
36183637 fn test_pop_byte() {
36193638 let mut s = ~" ABC ";
36203639 let b = unsafe{raw::pop_byte(&mut s)};
36213640 assert_eq!(s, ~" AB ");
3622- assert_eq!(b, 67u8);
3641+ assert_eq!(b, Some( 67u8) );
36233642 }
36243643
36253644 #[test]
0 commit comments