Update FromStr and FromStrRadix to return Result
Fixes build errors with Rust 1.0.0-nightly.
This commit is contained in:
parent
b324415930
commit
42edb63090
|
@ -60,7 +60,10 @@ extern crate "rustc-serialize" as rustc_serialize;
|
|||
|
||||
use Integer;
|
||||
|
||||
use core::num::ParseIntError;
|
||||
|
||||
use std::default::Default;
|
||||
use std::error::{Error, FromError};
|
||||
use std::iter::repeat;
|
||||
use std::num::{Int, ToPrimitive, FromPrimitive, FromStrRadix};
|
||||
use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub};
|
||||
|
@ -181,8 +184,10 @@ impl fmt::Display for BigUint {
|
|||
}
|
||||
|
||||
impl FromStr for BigUint {
|
||||
type Err = ParseBigIntError;
|
||||
|
||||
#[inline]
|
||||
fn from_str(s: &str) -> Option<BigUint> {
|
||||
fn from_str(s: &str) -> Result<BigUint, ParseBigIntError> {
|
||||
FromStrRadix::from_str_radix(s, 10)
|
||||
}
|
||||
}
|
||||
|
@ -815,13 +820,15 @@ fn to_str_radix_signed(me: &BigInt, radix: usize) -> String {
|
|||
}
|
||||
|
||||
impl FromStrRadix for BigUint {
|
||||
type Err = ParseBigIntError;
|
||||
|
||||
/// Creates and initializes a `BigUint`.
|
||||
#[inline]
|
||||
fn from_str_radix(s: &str, radix: usize) -> Option<BigUint> {
|
||||
fn from_str_radix(s: &str, radix: usize) -> Result<BigUint, ParseBigIntError> {
|
||||
let (base, unit_len) = get_radix_base(radix);
|
||||
let base_num = match base.to_biguint() {
|
||||
Some(base_num) => base_num,
|
||||
None => { return None; }
|
||||
None => { return Err(ParseBigIntError::Other); }
|
||||
};
|
||||
|
||||
let mut end = s.len();
|
||||
|
@ -829,8 +836,7 @@ impl FromStrRadix for BigUint {
|
|||
let mut power: BigUint = One::one();
|
||||
loop {
|
||||
let start = cmp::max(end, unit_len) - unit_len;
|
||||
match FromStrRadix::from_str_radix(&s[start .. end], radix) {
|
||||
Some(d) => {
|
||||
let d = try!(FromStrRadix::from_str_radix(&s[start .. end], radix));
|
||||
let d: Option<BigUint> = FromPrimitive::from_uint(d);
|
||||
match d {
|
||||
Some(d) => {
|
||||
|
@ -838,13 +844,10 @@ impl FromStrRadix for BigUint {
|
|||
// n += d * &power;
|
||||
n = n + d * &power;
|
||||
}
|
||||
None => { return None; }
|
||||
}
|
||||
}
|
||||
None => { return None; }
|
||||
None => { return Err(ParseBigIntError::Other); }
|
||||
}
|
||||
if end <= unit_len {
|
||||
return Some(n);
|
||||
return Ok(n);
|
||||
}
|
||||
end -= unit_len;
|
||||
// FIXME(#5992): assignment operator overloads
|
||||
|
@ -956,7 +959,7 @@ impl BigUint {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn parse_bytes(buf: &[u8], radix: usize) -> Option<BigUint> {
|
||||
str::from_utf8(buf).ok().and_then(|s| FromStrRadix::from_str_radix(s, radix))
|
||||
str::from_utf8(buf).ok().and_then(|s| FromStrRadix::from_str_radix(s, radix).ok())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -1110,8 +1113,10 @@ impl<S: hash::Hasher + hash::Writer> hash::Hash<S> for BigInt {
|
|||
}
|
||||
|
||||
impl FromStr for BigInt {
|
||||
type Err = ParseBigIntError;
|
||||
|
||||
#[inline]
|
||||
fn from_str(s: &str) -> Option<BigInt> {
|
||||
fn from_str(s: &str) -> Result<BigInt, ParseBigIntError> {
|
||||
FromStrRadix::from_str_radix(s, 10)
|
||||
}
|
||||
}
|
||||
|
@ -1521,10 +1526,12 @@ impl_to_bigint!(u32, FromPrimitive::from_u32);
|
|||
impl_to_bigint!(u64, FromPrimitive::from_u64);
|
||||
|
||||
impl FromStrRadix for BigInt {
|
||||
type Err = ParseBigIntError;
|
||||
|
||||
/// Creates and initializes a BigInt.
|
||||
#[inline]
|
||||
fn from_str_radix(s: &str, radix: usize) -> Option<BigInt> {
|
||||
if s.is_empty() { return None; }
|
||||
fn from_str_radix(s: &str, radix: usize) -> Result<BigInt, ParseBigIntError> {
|
||||
if s.is_empty() { return Err(ParseBigIntError::Other); }
|
||||
let mut sign = Plus;
|
||||
let mut start = 0;
|
||||
if s.starts_with("-") {
|
||||
|
@ -1703,7 +1710,7 @@ impl BigInt {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn parse_bytes(buf: &[u8], radix: usize) -> Option<BigInt> {
|
||||
str::from_utf8(buf).ok().and_then(|s| FromStrRadix::from_str_radix(s, radix))
|
||||
str::from_utf8(buf).ok().and_then(|s| FromStrRadix::from_str_radix(s, radix).ok())
|
||||
}
|
||||
|
||||
|
||||
|
@ -1741,6 +1748,31 @@ impl BigInt {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ParseBigIntError {
|
||||
ParseInt(ParseIntError),
|
||||
Other,
|
||||
}
|
||||
|
||||
impl fmt::Display for ParseBigIntError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
&ParseBigIntError::ParseInt(ref e) => e.fmt(f),
|
||||
&ParseBigIntError::Other => "failed to parse provided string".fmt(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for ParseBigIntError {
|
||||
fn description(&self) -> &str { "failed to parse bigint/biguint" }
|
||||
}
|
||||
|
||||
impl FromError<ParseIntError> for ParseBigIntError {
|
||||
fn from_error(err: ParseIntError) -> ParseBigIntError {
|
||||
ParseBigIntError::ParseInt(err)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod biguint_tests {
|
||||
use Integer;
|
||||
|
@ -1929,7 +1961,7 @@ mod biguint_tests {
|
|||
#[test]
|
||||
fn test_shl() {
|
||||
fn check(s: &str, shift: usize, ans: &str) {
|
||||
let opt_biguint: Option<BigUint> = FromStrRadix::from_str_radix(s, 16);
|
||||
let opt_biguint: Option<BigUint> = FromStrRadix::from_str_radix(s, 16).ok();
|
||||
let bu = to_str_radix(&(opt_biguint.unwrap() << shift), 16);
|
||||
assert_eq!(bu.as_slice(), ans);
|
||||
}
|
||||
|
@ -2051,7 +2083,7 @@ mod biguint_tests {
|
|||
fn test_shr() {
|
||||
fn check(s: &str, shift: usize, ans: &str) {
|
||||
let opt_biguint: Option<BigUint> =
|
||||
FromStrRadix::from_str_radix(s, 16);
|
||||
FromStrRadix::from_str_radix(s, 16).ok();
|
||||
let bu = to_str_radix(&(opt_biguint.unwrap() >> shift), 16);
|
||||
assert_eq!(bu.as_slice(), ans);
|
||||
}
|
||||
|
@ -2571,12 +2603,12 @@ mod biguint_tests {
|
|||
}
|
||||
}
|
||||
|
||||
let zed: Option<BigUint> = FromStrRadix::from_str_radix("Z", 10);
|
||||
let zed: Option<BigUint> = FromStrRadix::from_str_radix("Z", 10).ok();
|
||||
assert_eq!(zed, None);
|
||||
let blank: Option<BigUint> = FromStrRadix::from_str_radix("_", 2);
|
||||
let blank: Option<BigUint> = FromStrRadix::from_str_radix("_", 2).ok();
|
||||
assert_eq!(blank, None);
|
||||
let minus_one: Option<BigUint> = FromStrRadix::from_str_radix("-1",
|
||||
10);
|
||||
10).ok();
|
||||
assert_eq!(minus_one, None);
|
||||
}
|
||||
|
||||
|
@ -2596,7 +2628,7 @@ mod biguint_tests {
|
|||
fn check(n: usize, s: &str) {
|
||||
let n = factor(n);
|
||||
let ans = match FromStrRadix::from_str_radix(s, 10) {
|
||||
Some(x) => x, None => panic!()
|
||||
Ok(x) => x, Err(_) => panic!()
|
||||
};
|
||||
assert_eq!(n, ans);
|
||||
}
|
||||
|
@ -3256,7 +3288,7 @@ mod bigint_tests {
|
|||
let x: BigInt = FromPrimitive::from_int(n).unwrap();
|
||||
x
|
||||
});
|
||||
assert_eq!(FromStrRadix::from_str_radix(s, 10), ans);
|
||||
assert_eq!(FromStrRadix::from_str_radix(s, 10).ok(), ans);
|
||||
}
|
||||
check("10", Some(10));
|
||||
check("1", Some(1));
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
//!
|
||||
//! [newt]: https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
|
||||
|
||||
#![feature(slicing_syntax)]
|
||||
#![feature(slicing_syntax, core)]
|
||||
#![cfg_attr(test, deny(warnings))]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
|
@ -54,6 +54,7 @@
|
|||
#![allow(unstable)]
|
||||
|
||||
extern crate "rustc-serialize" as rustc_serialize;
|
||||
extern crate core;
|
||||
|
||||
pub use bigint::{BigInt, BigUint};
|
||||
pub use rational::{Rational, BigRational};
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
use Integer;
|
||||
|
||||
use std::cmp;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::ops::{Add, Div, Mul, Neg, Rem, Sub};
|
||||
use std::str::FromStr;
|
||||
|
@ -419,42 +420,60 @@ impl<T: fmt::Display + Eq + One> fmt::Display for Ratio<T> {
|
|||
|
||||
impl<T: FromStr + Clone + Integer + PartialOrd>
|
||||
FromStr for Ratio<T> {
|
||||
type Err = ParseRatioError;
|
||||
|
||||
/// Parses `numer/denom` or just `numer`.
|
||||
fn from_str(s: &str) -> Option<Ratio<T>> {
|
||||
fn from_str(s: &str) -> Result<Ratio<T>, ParseRatioError> {
|
||||
let mut split = s.splitn(1, '/');
|
||||
|
||||
let num = split.next().and_then(|n| FromStr::from_str(n));
|
||||
let den = split.next().or(Some("1")).and_then(|d| FromStr::from_str(d));
|
||||
let n = try!(split.next().ok_or(ParseRatioError));
|
||||
let num = try!(FromStr::from_str(n).map_err(|_| ParseRatioError));
|
||||
|
||||
match (num, den) {
|
||||
(Some(n), Some(d)) => Some(Ratio::new(n, d)),
|
||||
_ => None
|
||||
}
|
||||
let d = split.next().unwrap_or("1");
|
||||
let den = try!(FromStr::from_str(d).map_err(|_| ParseRatioError));
|
||||
|
||||
Ok(Ratio::new(num, den))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: FromStrRadix + Clone + Integer + PartialOrd>
|
||||
FromStrRadix for Ratio<T> {
|
||||
type Err = ParseRatioError;
|
||||
|
||||
/// Parses `numer/denom` where the numbers are in base `radix`.
|
||||
fn from_str_radix(s: &str, radix: usize) -> Option<Ratio<T>> {
|
||||
fn from_str_radix(s: &str, radix: usize) -> Result<Ratio<T>, ParseRatioError> {
|
||||
let split: Vec<&str> = s.splitn(1, '/').collect();
|
||||
if split.len() < 2 {
|
||||
None
|
||||
Err(ParseRatioError)
|
||||
} else {
|
||||
let a_option: Option<T> = FromStrRadix::from_str_radix(
|
||||
let a_result: Result<T, _> = FromStrRadix::from_str_radix(
|
||||
split[0],
|
||||
radix);
|
||||
a_option.and_then(|a| {
|
||||
let b_option: Option<T> =
|
||||
FromStrRadix::from_str_radix(split[1], radix);
|
||||
b_option.and_then(|b| {
|
||||
Some(Ratio::new(a.clone(), b.clone()))
|
||||
radix).map_err(|_| ParseRatioError);
|
||||
a_result.and_then(|a| {
|
||||
let b_result: Result<T, _> =
|
||||
FromStrRadix::from_str_radix(split[1], radix).map_err(|_| ParseRatioError);
|
||||
b_result.and_then(|b| {
|
||||
Ok(Ratio::new(a.clone(), b.clone()))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Bubble up specific errors
|
||||
#[derive(Copy, Debug, PartialEq)]
|
||||
pub struct ParseRatioError;
|
||||
|
||||
impl fmt::Display for ParseRatioError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
"failed to parse provided string".fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for ParseRatioError {
|
||||
fn description(&self) -> &str { "failed to parse bigint/biguint" }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
|
@ -740,7 +759,7 @@ mod test {
|
|||
#[test]
|
||||
fn test_to_from_str() {
|
||||
fn test(r: Rational, s: String) {
|
||||
assert_eq!(FromStr::from_str(&s[]), Some(r));
|
||||
assert_eq!(FromStr::from_str(&s[]), Ok(r));
|
||||
assert_eq!(r.to_string(), s);
|
||||
}
|
||||
test(_1, "1".to_string());
|
||||
|
@ -753,8 +772,8 @@ mod test {
|
|||
#[test]
|
||||
fn test_from_str_fail() {
|
||||
fn test(s: &str) {
|
||||
let rational: Option<Rational> = FromStr::from_str(s);
|
||||
assert_eq!(rational, None);
|
||||
let rational: Result<Rational, _> = FromStr::from_str(s);
|
||||
assert!(rational.is_err());
|
||||
}
|
||||
|
||||
let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1"];
|
||||
|
|
Loading…
Reference in New Issue