Sfoglia il codice sorgente

Merge pull request #58 from mbrubeck/nightly

Update to build with Rust 1.0.0-nightly
Alex Crichton 10 anni fa
parent
commit
aadcbef4ba
3 ha cambiato i file con 100 aggiunte e 50 eliminazioni
  1. 60 28
      src/bigint.rs
  2. 2 3
      src/lib.rs
  3. 38 19
      src/rational.rs

+ 60 - 28
src/bigint.rs

@@ -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,22 +836,18 @@ 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) {
+            let d = try!(FromStrRadix::from_str_radix(&s[start .. end], radix));
+            let d: Option<BigUint> = FromPrimitive::from_uint(d);
+            match d {
                 Some(d) => {
-                    let d: Option<BigUint> = FromPrimitive::from_uint(d);
-                    match d {
-                        Some(d) => {
-                            // FIXME(#5992): assignment operator overloads
-                            // n += d * &power;
-                            n = n + d * &power;
-                        }
-                        None => { return None; }
-                    }
+                    // FIXME(#5992): assignment operator overloads
+                    // n += d * &power;
+                    n = n + d * &power;
                 }
-                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]
@@ -1037,7 +1040,7 @@ fn get_radix_base(radix: usize) -> (DoubleBigDigit, usize) {
 }
 
 /// A Sign is a `BigInt`'s composing element.
-#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone, Show, RustcEncodable, RustcDecodable)]
+#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum Sign { Minus, NoSign, Plus }
 
 impl Neg for Sign {
@@ -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));

+ 2 - 3
src/lib.rs

@@ -44,16 +44,15 @@
 //!
 //! [newt]: https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
 
-#![feature(slicing_syntax)]
+#![feature(slicing_syntax, collections, core, hash, rand, std_misc)]
 #![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",
        html_root_url = "http://doc.rust-lang.org/num/",
        html_playground_url = "http://play.rust-lang.org/")]
 
-#![allow(unstable)]
-
 extern crate "rustc-serialize" as rustc_serialize;
+extern crate core;
 
 pub use bigint::{BigInt, BigUint};
 pub use rational::{Rational, BigRational};

+ 38 - 19
src/rational.rs

@@ -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"];