change return type of slice_shift_char
`slice_shift_char` splits a `str` into it's leading `char` and the remainder of the `str`. Currently, it returns a `(Option<char>, &str)` such that: "bar".slice_shift_char() => (Some('b'), "ar") "ar".slice_shift_char() => (Some('a'), "r") "r".slice_shift_char() => (Some('r'), "") "".slice_shift_char() => (None, "") This is a little odd. Either a `str` can be split into both a head and a tail or it cannot. So the return type should be `Option<(char, &str)>`. With the current behaviour, in the case of the empty string, the `str` returned is meaningless - it is always the empty string. This commit changes slice_shift_char so that: "bar".slice_shift_char() => Some(('b', "ar")) "ar".slice_shift_char() => Some(('a', "r")) "r".slice_shift_char() => Some(('r', "")) "".slice_shift_char() => None [breaking-change]
This commit is contained in:
parent
803aacd5ae
commit
197a0ac481
5 changed files with 25 additions and 25 deletions
|
@ -1254,13 +1254,13 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slice_shift_char() {
|
fn test_slice_shift_char() {
|
||||||
let data = "ประเทศไทย中";
|
let data = "ประเทศไทย中";
|
||||||
assert_eq!(data.slice_shift_char(), (Some('ป'), "ระเทศไทย中"));
|
assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中")));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slice_shift_char_2() {
|
fn test_slice_shift_char_2() {
|
||||||
let empty = "";
|
let empty = "";
|
||||||
assert_eq!(empty.slice_shift_char(), (None, ""));
|
assert_eq!(empty.slice_shift_char(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1455,10 +1455,10 @@ macro_rules! from_str_radix_float_impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
let (is_positive, src) = match src.slice_shift_char() {
|
let (is_positive, src) = match src.slice_shift_char() {
|
||||||
(None, _) => return None,
|
None => return None,
|
||||||
(Some('-'), "") => return None,
|
Some(('-', "")) => return None,
|
||||||
(Some('-'), src) => (false, src),
|
Some(('-', src)) => (false, src),
|
||||||
(Some(_), _) => (true, src),
|
Some((_, _)) => (true, src),
|
||||||
};
|
};
|
||||||
|
|
||||||
// The significand to accumulate
|
// The significand to accumulate
|
||||||
|
@ -1561,10 +1561,10 @@ macro_rules! from_str_radix_float_impl {
|
||||||
// Parse the exponent as decimal integer
|
// Parse the exponent as decimal integer
|
||||||
let src = src[offset..];
|
let src = src[offset..];
|
||||||
let (is_positive, exp) = match src.slice_shift_char() {
|
let (is_positive, exp) = match src.slice_shift_char() {
|
||||||
(Some('-'), src) => (false, from_str::<uint>(src)),
|
Some(('-', src)) => (false, from_str::<uint>(src)),
|
||||||
(Some('+'), src) => (true, from_str::<uint>(src)),
|
Some(('+', src)) => (true, from_str::<uint>(src)),
|
||||||
(Some(_), _) => (true, from_str::<uint>(src)),
|
Some((_, _)) => (true, from_str::<uint>(src)),
|
||||||
(None, _) => return None,
|
None => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
match (is_positive, exp) {
|
match (is_positive, exp) {
|
||||||
|
@ -1604,7 +1604,7 @@ macro_rules! from_str_radix_int_impl {
|
||||||
let is_signed_ty = (0 as $T) > Int::min_value();
|
let is_signed_ty = (0 as $T) > Int::min_value();
|
||||||
|
|
||||||
match src.slice_shift_char() {
|
match src.slice_shift_char() {
|
||||||
(Some('-'), src) if is_signed_ty => {
|
Some(('-', src)) if is_signed_ty => {
|
||||||
// The number is negative
|
// The number is negative
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
for c in src.chars() {
|
for c in src.chars() {
|
||||||
|
@ -1623,7 +1623,7 @@ macro_rules! from_str_radix_int_impl {
|
||||||
}
|
}
|
||||||
Some(result)
|
Some(result)
|
||||||
},
|
},
|
||||||
(Some(_), _) => {
|
Some((_, _)) => {
|
||||||
// The number is signed
|
// The number is signed
|
||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
for c in src.chars() {
|
for c in src.chars() {
|
||||||
|
@ -1642,7 +1642,7 @@ macro_rules! from_str_radix_int_impl {
|
||||||
}
|
}
|
||||||
Some(result)
|
Some(result)
|
||||||
},
|
},
|
||||||
(None, _) => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1808,21 +1808,21 @@ pub trait StrPrelude for Sized? {
|
||||||
/// it. This does not allocate a new string; instead, it returns a
|
/// it. This does not allocate a new string; instead, it returns a
|
||||||
/// slice that point one character beyond the character that was
|
/// slice that point one character beyond the character that was
|
||||||
/// shifted. If the string does not contain any characters,
|
/// shifted. If the string does not contain any characters,
|
||||||
/// a tuple of None and an empty string is returned instead.
|
/// None is returned instead.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// let s = "Löwe 老虎 Léopard";
|
/// let s = "Löwe 老虎 Léopard";
|
||||||
/// let (c, s1) = s.slice_shift_char();
|
/// let (c, s1) = s.slice_shift_char().unwrap();
|
||||||
/// assert_eq!(c, Some('L'));
|
/// assert_eq!(c, 'L');
|
||||||
/// assert_eq!(s1, "öwe 老虎 Léopard");
|
/// assert_eq!(s1, "öwe 老虎 Léopard");
|
||||||
///
|
///
|
||||||
/// let (c, s2) = s1.slice_shift_char();
|
/// let (c, s2) = s1.slice_shift_char().unwrap();
|
||||||
/// assert_eq!(c, Some('ö'));
|
/// assert_eq!(c, 'ö');
|
||||||
/// assert_eq!(s2, "we 老虎 Léopard");
|
/// assert_eq!(s2, "we 老虎 Léopard");
|
||||||
/// ```
|
/// ```
|
||||||
fn slice_shift_char<'a>(&'a self) -> (Option<char>, &'a str);
|
fn slice_shift_char<'a>(&'a self) -> Option<(char, &'a str)>;
|
||||||
|
|
||||||
/// Returns the byte offset of an inner slice relative to an enclosing outer slice.
|
/// Returns the byte offset of an inner slice relative to an enclosing outer slice.
|
||||||
///
|
///
|
||||||
|
@ -2194,13 +2194,13 @@ impl StrPrelude for str {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn slice_shift_char(&self) -> (Option<char>, &str) {
|
fn slice_shift_char(&self) -> Option<(char, &str)> {
|
||||||
if self.is_empty() {
|
if self.is_empty() {
|
||||||
return (None, self);
|
None
|
||||||
} else {
|
} else {
|
||||||
let CharRange {ch, next} = self.char_range_at(0u);
|
let CharRange {ch, next} = self.char_range_at(0u);
|
||||||
let next_s = unsafe { raw::slice_bytes(self, next, self.len()) };
|
let next_s = unsafe { raw::slice_bytes(self, next, self.len()) };
|
||||||
return (Some(ch), next_s);
|
Some((ch, next_s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,8 +96,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
||||||
// cannot be shared with any other operand (usually when
|
// cannot be shared with any other operand (usually when
|
||||||
// a register is clobbered early.)
|
// a register is clobbered early.)
|
||||||
let output = match constraint.get().slice_shift_char() {
|
let output = match constraint.get().slice_shift_char() {
|
||||||
(Some('='), _) => None,
|
Some(('=', _)) => None,
|
||||||
(Some('+'), operand) => {
|
Some(('+', operand)) => {
|
||||||
Some(token::intern_and_get_ident(format!(
|
Some(token::intern_and_get_ident(format!(
|
||||||
"={}",
|
"={}",
|
||||||
operand).as_slice()))
|
operand).as_slice()))
|
||||||
|
|
|
@ -1853,7 +1853,7 @@ impl<'a> State<'a> {
|
||||||
try!(self.commasep(Inconsistent, a.outputs.as_slice(),
|
try!(self.commasep(Inconsistent, a.outputs.as_slice(),
|
||||||
|s, &(ref co, ref o, is_rw)| {
|
|s, &(ref co, ref o, is_rw)| {
|
||||||
match co.get().slice_shift_char() {
|
match co.get().slice_shift_char() {
|
||||||
(Some('='), operand) if is_rw => {
|
Some(('=', operand)) if is_rw => {
|
||||||
try!(s.print_string(format!("+{}", operand).as_slice(),
|
try!(s.print_string(format!("+{}", operand).as_slice(),
|
||||||
ast::CookedStr))
|
ast::CookedStr))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue