Auto merge of #28826 - arthurprs:leading_plus, r=alexcrichton
Closes #27580
This commit is contained in:
commit
64c4b51dd6
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue