@@ -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 } ;
@@ -1464,23 +1465,31 @@ pub mod raw {
14641465 }
14651466
14661467 /// Removes the last byte from a string and returns it.
1468+ /// Returns None when an empty string is passed.
14671469 /// 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 > {
14691471 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+ }
14741479 }
14751480
14761481 /// Removes the first byte from a string and returns it.
1482+ /// Returns None when an empty string is passed.
14771483 /// 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 > {
14791485 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+ }
14841493 }
14851494
14861495 /// Access the str in its vector representation.
@@ -2273,25 +2282,22 @@ pub trait StrSlice<'a> {
22732282 /// Retrieves the first character from a string slice and returns
22742283 /// it. This does not allocate a new string; instead, it returns a
22752284 /// 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.
22812287 ///
22822288 /// # Example
22832289 ///
22842290 /// ```rust
22852291 /// let s = "Löwe 老虎 Léopard";
22862292 /// let (c, s1) = s.slice_shift_char();
2287- /// assert_eq!(c, 'L');
2293+ /// assert_eq!(c, Some( 'L') );
22882294 /// assert_eq!(s1, "öwe 老虎 Léopard");
22892295 ///
22902296 /// let (c, s2) = s1.slice_shift_char();
2291- /// assert_eq!(c, 'ö');
2297+ /// assert_eq!(c, Some( 'ö') );
22922298 /// assert_eq!(s2, "we 老虎 Léopard");
22932299 /// ```
2294- fn slice_shift_char( & self ) -> ( char , & ' a str ) ;
2300+ fn slice_shift_char( & self ) -> ( Option < char > , & ' a str ) ;
22952301
22962302 /// Levenshtein Distance between two strings.
22972303 fn lev_distance( & self , t: & str ) -> uint;
@@ -2744,10 +2750,14 @@ impl<'a> StrSlice<'a> for &'a str {
27442750 }
27452751
27462752 #[ 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+ }
27512761 }
27522762
27532763 fn lev_distance( & self , t: & str ) -> uint {
@@ -2810,19 +2820,13 @@ pub trait OwnedStr {
28102820 /// Appends a character to the back of a string
28112821 fn push_char( & mut self , c: char ) ;
28122822
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 >;
28192826
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 >;
28262830
28272831 /// Prepend a char to a string
28282832 fn unshift_char( & mut self , ch: char ) ;
@@ -2925,19 +2929,26 @@ impl OwnedStr for ~str {
29252929 }
29262930
29272931 #[ inline]
2928- fn pop_char( & mut self ) -> char {
2932+ fn pop_char( & mut self ) -> Option < char > {
29292933 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+ }
29342941 }
29352942
29362943 #[ 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+ }
29412952 }
29422953
29432954 #[ inline]
@@ -3148,22 +3159,23 @@ mod tests {
31483159 let mut data = ~"ประเทศไทย中华";
31493160 let cc = data.pop_char();
31503161 assert_eq!(~" ประเทศไทย中", data);
3151- assert_eq!('华', cc);
3162+ assert_eq!(Some( '华') , cc);
31523163 }
31533164
31543165 #[test]
31553166 fn test_pop_char_2() {
31563167 let mut data2 = ~" 华";
31573168 let cc2 = data2.pop_char();
31583169 assert_eq!(~" ", data2);
3159- assert_eq!('华', cc2);
3170+ assert_eq!(Some( '华') , cc2);
31603171 }
31613172
31623173 #[test]
3163- #[should_fail]
3164- fn test_pop_char_fail() {
3174+ fn test_pop_char_empty() {
31653175 let mut data = ~" ";
3166- let _cc3 = data.pop_char();
3176+ let cc3 = data.pop_char();
3177+ assert_eq!(~" ", data);
3178+ assert_eq!(None, cc3);
31673179 }
31683180
31693181 #[test]
@@ -3182,7 +3194,7 @@ mod tests {
31823194 let mut data = ~" ประเทศไทย中";
31833195 let cc = data.shift_char();
31843196 assert_eq!(~" ระเทศไทย中", data);
3185- assert_eq!('ป', cc);
3197+ assert_eq!(Some( 'ป') , cc);
31863198 }
31873199
31883200 #[test]
@@ -3599,6 +3611,18 @@ mod tests {
35993611 assert!( !" _ " . is_whitespace( ) ) ;
36003612 }
36013613
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+
36023626 #[ test]
36033627 fn test_push_byte( ) {
36043628 let mut s = ~"ABC ";
@@ -3611,15 +3635,15 @@ mod tests {
36113635 let mut s = ~" ABC ";
36123636 let b = unsafe{raw::shift_byte(&mut s)};
36133637 assert_eq!(s, ~" BC ");
3614- assert_eq!(b, 65u8);
3638+ assert_eq!(b, Some( 65u8) );
36153639 }
36163640
36173641 #[test]
36183642 fn test_pop_byte() {
36193643 let mut s = ~" ABC ";
36203644 let b = unsafe{raw::pop_byte(&mut s)};
36213645 assert_eq!(s, ~" AB ");
3622- assert_eq!(b, 67u8);
3646+ assert_eq!(b, Some( 67u8) );
36233647 }
36243648
36253649 #[test]
0 commit comments