Auto merge of #28826 - arthurprs:leading_plus, r=alexcrichton

Closes #27580
This commit is contained in:
bors 2015-10-08 17:19:59 +00:00
commit 64c4b51dd6
2 changed files with 49 additions and 40 deletions

View File

@ -1387,50 +1387,51 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32)
// of multi-byte sequences // of multi-byte sequences
let src = src.as_bytes(); let src = src.as_bytes();
match (src[0], &src[1..]) { let (is_positive, digits) = match src[0] {
(b'-', digits) if digits.is_empty() => Err(PIE { kind: Empty }), b'+' => (true, &src[1..]),
(b'-', digits) if is_signed_ty => { b'-' if is_signed_ty => (false, &src[1..]),
// The number is negative _ => (true, src)
let mut result = T::from_u32(0); };
for &c in digits {
let x = match (c as char).to_digit(radix) { if digits.is_empty() {
Some(x) => x, return Err(PIE { kind: Empty });
None => return Err(PIE { kind: InvalidDigit }), }
};
result = match result.checked_mul(radix) { let mut result = T::from_u32(0);
Some(result) => result, if is_positive {
None => return Err(PIE { kind: Underflow }), // The number is positive
}; for &c in digits {
result = match result.checked_sub(x) { let x = match (c as char).to_digit(radix) {
Some(result) => result, Some(x) => x,
None => return Err(PIE { kind: Underflow }),
};
}
Ok(result)
},
(c, digits) => {
// The number is signed
let mut result = match (c as char).to_digit(radix) {
Some(x) => T::from_u32(x),
None => return Err(PIE { kind: InvalidDigit }), None => return Err(PIE { kind: InvalidDigit }),
}; };
for &c in digits { result = match result.checked_mul(radix) {
let x = match (c as char).to_digit(radix) { Some(result) => result,
Some(x) => x, None => return Err(PIE { kind: Overflow }),
None => return Err(PIE { kind: InvalidDigit }), };
}; result = match result.checked_add(x) {
result = match result.checked_mul(radix) { Some(result) => result,
Some(result) => result, None => return Err(PIE { kind: Overflow }),
None => return Err(PIE { kind: Overflow }), };
}; }
result = match result.checked_add(x) { } else {
Some(result) => result, // The number is negative
None => return Err(PIE { kind: Overflow }), for &c in digits {
}; let x = match (c as char).to_digit(radix) {
} Some(x) => x,
Ok(result) None => return Err(PIE { kind: InvalidDigit }),
};
result = match result.checked_mul(radix) {
Some(result) => result,
None => return Err(PIE { kind: Underflow }),
};
result = match result.checked_sub(x) {
Some(result) => result,
None => return Err(PIE { kind: Underflow }),
};
} }
} }
Ok(result)
} }
/// An error which can be returned when parsing an integer. /// An error which can be returned when parsing an integer.

View File

@ -118,15 +118,23 @@ mod tests {
assert_eq!("-9223372036854775809".parse::<i64>().ok(), None); assert_eq!("-9223372036854775809".parse::<i64>().ok(), None);
} }
#[test]
fn test_leading_plus() {
assert_eq!("+127".parse::<u8>().ok(), Some(127u8));
assert_eq!("+9223372036854775807".parse::<i64>().ok(), Some(9223372036854775807i64));
}
#[test] #[test]
fn test_invalid() { fn test_invalid() {
assert_eq!("--129".parse::<i8>().ok(), None); assert_eq!("--129".parse::<i8>().ok(), None);
assert_eq!("++129".parse::<i8>().ok(), None);
assert_eq!("Съешь".parse::<u8>().ok(), None); assert_eq!("Съешь".parse::<u8>().ok(), None);
} }
#[test] #[test]
fn test_empty() { fn test_empty() {
assert_eq!("-".parse::<i8>().ok(), None); assert_eq!("-".parse::<i8>().ok(), None);
assert_eq!("+".parse::<i8>().ok(), None);
assert_eq!("".parse::<u8>().ok(), None); assert_eq!("".parse::<u8>().ok(), None);
} }
} }