libstd: Change slice_shift_char
, shift_char
, pop_char
, shift_byte
and pop_byte
to return an Option instead of failing
This commit is contained in:
parent
62f1d68439
commit
0349f2ae8a
@ -369,11 +369,11 @@ fn matches_from(&self,
|
||||
return EntirePatternDoesntMatch;
|
||||
}
|
||||
|
||||
let (c, next) = file.slice_shift_char();
|
||||
if require_literal(c) {
|
||||
let (some_c, next) = file.slice_shift_char();
|
||||
if require_literal(some_c.unwrap()) {
|
||||
return SubPatternDoesntMatch;
|
||||
}
|
||||
prev_char.set(Some(c));
|
||||
prev_char.set(some_c);
|
||||
file = next;
|
||||
}
|
||||
}
|
||||
@ -382,7 +382,8 @@ fn matches_from(&self,
|
||||
return EntirePatternDoesntMatch;
|
||||
}
|
||||
|
||||
let (c, next) = file.slice_shift_char();
|
||||
let (some_c, next) = file.slice_shift_char();
|
||||
let c = some_c.unwrap();
|
||||
let matches = match *token {
|
||||
AnyChar => {
|
||||
!require_literal(c)
|
||||
@ -403,7 +404,7 @@ fn matches_from(&self,
|
||||
if !matches {
|
||||
return SubPatternDoesntMatch;
|
||||
}
|
||||
prev_char.set(Some(c));
|
||||
prev_char.set(some_c);
|
||||
file = next;
|
||||
}
|
||||
}
|
||||
|
@ -1355,6 +1355,7 @@ pub mod raw {
|
||||
use libc;
|
||||
use ptr;
|
||||
use ptr::RawPtr;
|
||||
use option::{Option, Some, None};
|
||||
use str::{is_utf8, OwnedStr, StrSlice};
|
||||
use vec;
|
||||
use vec::{MutableVector, ImmutableVector, OwnedVector};
|
||||
@ -1465,22 +1466,28 @@ pub unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) {
|
||||
|
||||
/// Removes the last byte from a string and returns it.
|
||||
/// The caller must preserve the valid UTF-8 property.
|
||||
pub unsafe fn pop_byte(s: &mut ~str) -> u8 {
|
||||
pub unsafe fn pop_byte(s: &mut ~str) -> Option<u8> {
|
||||
let len = s.len();
|
||||
assert!((len > 0u));
|
||||
let b = s[len - 1u];
|
||||
s.set_len(len - 1);
|
||||
return b;
|
||||
if len == 0u {
|
||||
return None;
|
||||
} else {
|
||||
let b = s[len - 1u];
|
||||
s.set_len(len - 1);
|
||||
return Some(b);
|
||||
}
|
||||
}
|
||||
|
||||
/// Removes the first byte from a string and returns it.
|
||||
/// The caller must preserve the valid UTF-8 property.
|
||||
pub unsafe fn shift_byte(s: &mut ~str) -> u8 {
|
||||
pub unsafe fn shift_byte(s: &mut ~str) -> Option<u8> {
|
||||
let len = s.len();
|
||||
assert!((len > 0u));
|
||||
let b = s[0];
|
||||
*s = s.slice(1, len).to_owned();
|
||||
return b;
|
||||
if len == 0u {
|
||||
return None;
|
||||
} else {
|
||||
let b = s[0];
|
||||
*s = s.slice(1, len).to_owned();
|
||||
return Some(b);
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the str in its vector representation.
|
||||
@ -2291,7 +2298,7 @@ pub trait StrSlice<'a> {
|
||||
/// assert_eq!(c, 'ö');
|
||||
/// assert_eq!(s2, "we 老虎 Léopard");
|
||||
/// ```
|
||||
fn slice_shift_char(&self) -> (char, &'a str);
|
||||
fn slice_shift_char(&self) -> (Option<char>, &'a str);
|
||||
|
||||
/// Levenshtein Distance between two strings.
|
||||
fn lev_distance(&self, t: &str) -> uint;
|
||||
@ -2744,10 +2751,14 @@ fn repeat(&self, nn: uint) -> ~str {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn slice_shift_char(&self) -> (char, &'a str) {
|
||||
let CharRange {ch, next} = self.char_range_at(0u);
|
||||
let next_s = unsafe { raw::slice_bytes(*self, next, self.len()) };
|
||||
return (ch, next_s);
|
||||
fn slice_shift_char(&self) -> (Option<char>, &'a str) {
|
||||
if self.is_empty() {
|
||||
return (None, *self);
|
||||
} else {
|
||||
let CharRange {ch, next} = self.char_range_at(0u);
|
||||
let next_s = unsafe { raw::slice_bytes(*self, next, self.len()) };
|
||||
return (Some(ch), next_s);
|
||||
}
|
||||
}
|
||||
|
||||
fn lev_distance(&self, t: &str) -> uint {
|
||||
@ -2815,14 +2826,14 @@ pub trait OwnedStr {
|
||||
/// # Failure
|
||||
///
|
||||
/// If the string does not contain any characters
|
||||
fn pop_char(&mut self) -> char;
|
||||
fn pop_char(&mut self) -> Option<char>;
|
||||
|
||||
/// Remove the first character from a string and return it
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// If the string does not contain any characters
|
||||
fn shift_char(&mut self) -> char;
|
||||
fn shift_char(&mut self) -> Option<char>;
|
||||
|
||||
/// Prepend a char to a string
|
||||
fn unshift_char(&mut self, ch: char);
|
||||
@ -2925,19 +2936,26 @@ fn push_char(&mut self, c: char) {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn pop_char(&mut self) -> char {
|
||||
fn pop_char(&mut self) -> Option<char> {
|
||||
let end = self.len();
|
||||
assert!(end > 0u);
|
||||
let CharRange {ch, next} = self.char_range_at_reverse(end);
|
||||
unsafe { self.set_len(next); }
|
||||
return ch;
|
||||
if end == 0u {
|
||||
return None;
|
||||
} else {
|
||||
let CharRange {ch, next} = self.char_range_at_reverse(end);
|
||||
unsafe { self.set_len(next); }
|
||||
return Some(ch);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn shift_char(&mut self) -> char {
|
||||
let CharRange {ch, next} = self.char_range_at(0u);
|
||||
*self = self.slice(next, self.len()).to_owned();
|
||||
return ch;
|
||||
fn shift_char(&mut self) -> Option<char> {
|
||||
if self.is_empty() {
|
||||
return None;
|
||||
} else {
|
||||
let CharRange {ch, next} = self.char_range_at(0u);
|
||||
*self = self.slice(next, self.len()).to_owned();
|
||||
return Some(ch);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -3148,7 +3166,7 @@ fn test_pop_char() {
|
||||
let mut data = ~"ประเทศไทย中华";
|
||||
let cc = data.pop_char();
|
||||
assert_eq!(~"ประเทศไทย中", data);
|
||||
assert_eq!('华', cc);
|
||||
assert_eq!(Some('华'), cc);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -3156,14 +3174,15 @@ fn test_pop_char_2() {
|
||||
let mut data2 = ~"华";
|
||||
let cc2 = data2.pop_char();
|
||||
assert_eq!(~"", data2);
|
||||
assert_eq!('华', cc2);
|
||||
assert_eq!(Some('华'), cc2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_pop_char_fail() {
|
||||
fn test_pop_char_empty() {
|
||||
let mut data = ~"";
|
||||
let _cc3 = data.pop_char();
|
||||
let cc3 = data.pop_char();
|
||||
assert_eq!(~"", data);
|
||||
assert_eq!(None, cc3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -3182,7 +3201,7 @@ fn test_shift_char() {
|
||||
let mut data = ~"ประเทศไทย中";
|
||||
let cc = data.shift_char();
|
||||
assert_eq!(~"ระเทศไทย中", data);
|
||||
assert_eq!('ป', cc);
|
||||
assert_eq!(Some('ป'), cc);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -3611,7 +3630,7 @@ fn test_shift_byte() {
|
||||
let mut s = ~"ABC";
|
||||
let b = unsafe{raw::shift_byte(&mut s)};
|
||||
assert_eq!(s, ~"BC");
|
||||
assert_eq!(b, 65u8);
|
||||
assert_eq!(b, Some(65u8));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -3619,7 +3638,7 @@ fn test_pop_byte() {
|
||||
let mut s = ~"ABC";
|
||||
let b = unsafe{raw::pop_byte(&mut s)};
|
||||
assert_eq!(s, ~"AB");
|
||||
assert_eq!(b, 67u8);
|
||||
assert_eq!(b, Some(67u8));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -42,12 +42,12 @@ pub fn main() {
|
||||
assert!((!str::is_utf8([0xf0_u8, 0xff_u8, 0xff_u8, 0x10_u8])));
|
||||
|
||||
let mut stack = ~"a×c€";
|
||||
assert_eq!(stack.pop_char(), '€');
|
||||
assert_eq!(stack.pop_char(), 'c');
|
||||
assert_eq!(stack.pop_char(), Some('€'));
|
||||
assert_eq!(stack.pop_char(), Some('c'));
|
||||
stack.push_char('u');
|
||||
assert!(stack == ~"a×u");
|
||||
assert_eq!(stack.shift_char(), 'a');
|
||||
assert_eq!(stack.shift_char(), '×');
|
||||
assert_eq!(stack.shift_char(), Some('a'));
|
||||
assert_eq!(stack.shift_char(), Some('×'));
|
||||
stack.unshift_char('ß');
|
||||
assert!(stack == ~"ßu");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user