Kaynağa Gözat

Auto merge of #171 - erickt:serde, r=hauleth

Add support for Serde 0.7.

Serde 0.7 dropped it's dependency on num, so this patch moves the implementations here. For the sake of a better implementation, this just serializes BigUint as a `Vec<u32>`, `BigInt` as a `(u8, Vec<u32>)`, `Complex<T>` as a `(T, T)`, and `Ratio<T>` as a `(T, T)`.
Homu 9 yıl önce
ebeveyn
işleme
9b0d4c91cb
5 değiştirilmiş dosya ile 137 ekleme ve 1 silme
  1. 2 1
      Cargo.toml
  2. 76 0
      src/bigint.rs
  3. 26 0
      src/complex.rs
  4. 3 0
      src/lib.rs
  5. 30 0
      src/rational.rs

+ 2 - 1
Cargo.toml

@@ -14,8 +14,9 @@ complex, rational, range iterators, generic integers, and more!
 """
 
 [dependencies]
-rustc-serialize = { version = "0.3.13", optional = true }
 rand = { version = "0.3.8", optional = true }
+rustc-serialize = { version = "0.3.13", optional = true }
+serde = { version = "^0.7.0", optional = true }
 
 [dev-dependencies]
 # Some tests of non-rand functionality still use rand because the tests

+ 76 - 0
src/bigint.rs

@@ -79,6 +79,9 @@ use std::{f32, f64};
 use std::{u8, i64, u64};
 use std::ascii::AsciiExt;
 
+#[cfg(feature = "serde")]
+use serde;
+
 // Some of the tests of non-RNG-based functionality are randomized using the
 // RNG-based functionality, so the RNG-based functionality needs to be enabled
 // for tests.
@@ -1723,6 +1726,27 @@ impl BigUint {
     }
 }
 
+#[cfg(feature = "serde")]
+impl serde::Serialize for BigUint {
+    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where
+        S: serde::Serializer
+    {
+        self.data.serialize(serializer)
+    }
+}
+
+#[cfg(feature = "serde")]
+impl serde::Deserialize for BigUint {
+    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where
+        D: serde::Deserializer,
+    {
+        let data = try!(Vec::deserialize(deserializer));
+        Ok(BigUint {
+            data: data,
+        })
+    }
+}
+
 // `DoubleBigDigit` size dependent
 /// Returns the greatest power of the radix <= big_digit::BASE
 #[inline]
@@ -1809,6 +1833,36 @@ impl Mul<Sign> for Sign {
     }
 }
 
+#[cfg(feature = "serde")]
+impl serde::Serialize for Sign {
+    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where
+        S: serde::Serializer
+    {
+        match *self {
+            Sign::Minus => (-1i8).serialize(serializer),
+            Sign::NoSign => 0i8.serialize(serializer),
+            Sign::Plus => 1i8.serialize(serializer),
+        }
+    }
+}
+
+#[cfg(feature = "serde")]
+impl serde::Deserialize for Sign {
+    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where
+        D: serde::Deserializer,
+    {
+        use serde::de::Error;
+
+        let sign: i8 = try!(serde::Deserialize::deserialize(deserializer));
+        match sign {
+            -1 => Ok(Sign::Minus),
+            0 => Ok(Sign::NoSign),
+            1 => Ok(Sign::Plus),
+            _ => Err(D::Error::invalid_value("sign must be -1, 0, or 1")),
+        }
+    }
+}
+
 /// A big signed integer type.
 #[derive(Clone, Debug, Hash)]
 #[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
@@ -2398,6 +2452,28 @@ impl From<BigUint> for BigInt {
     }
 }
 
+#[cfg(feature = "serde")]
+impl serde::Serialize for BigInt {
+    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where
+        S: serde::Serializer
+    {
+        (self.sign, &self.data).serialize(serializer)
+    }
+}
+
+#[cfg(feature = "serde")]
+impl serde::Deserialize for BigInt {
+    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where
+        D: serde::Deserializer,
+    {
+        let (sign, data) = try!(serde::Deserialize::deserialize(deserializer));
+        Ok(BigInt {
+            sign: sign,
+            data: data,
+        })
+    }
+}
+
 /// A generic trait for converting a value to a `BigInt`.
 pub trait ToBigInt {
     /// Converts the value of `self` to a `BigInt`.

+ 26 - 0
src/complex.rs

@@ -14,6 +14,9 @@
 use std::fmt;
 use std::ops::{Add, Div, Mul, Neg, Sub};
 
+#[cfg(feature = "serde")]
+use serde;
+
 use {Zero, One, Num, Float};
 
 // FIXME #1284: handle complex NaN & infinity etc. This
@@ -567,6 +570,29 @@ impl<T> fmt::Display for Complex<T> where
     }
 }
 
+#[cfg(feature = "serde")]
+impl<T> serde::Serialize for Complex<T>
+    where T: serde::Serialize
+{
+    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where
+        S: serde::Serializer
+    {
+        (&self.re, &self.im).serialize(serializer)
+    }
+}
+
+#[cfg(feature = "serde")]
+impl<T> serde::Deserialize for Complex<T> where
+    T: serde::Deserialize + Num + Clone
+{
+    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where
+        D: serde::Deserializer,
+    {
+        let (re, im) = try!(serde::Deserialize::deserialize(deserializer));
+        Ok(Complex::new(re, im))
+    }
+}
+
 #[cfg(test)]
 mod test {
     #![allow(non_upper_case_globals)]

+ 3 - 0
src/lib.rs

@@ -66,6 +66,9 @@ extern crate rustc_serialize;
 #[cfg(any(feature = "rand", all(feature = "bigint", test)))]
 extern crate rand;
 
+#[cfg(feature = "serde")]
+extern crate serde;
+
 #[cfg(feature = "bigint")]
 pub use bigint::{BigInt, BigUint};
 #[cfg(feature = "rational")]

+ 30 - 0
src/rational.rs

@@ -18,6 +18,9 @@ use std::fmt;
 use std::ops::{Add, Div, Mul, Neg, Rem, Sub};
 use std::str::FromStr;
 
+#[cfg(feature = "serde")]
+use serde;
+
 #[cfg(feature = "bigint")]
 use bigint::{BigInt, BigUint, Sign};
 use traits::{FromPrimitive, Float, PrimInt};
@@ -528,6 +531,33 @@ impl<T: FromStr + Clone + Integer> FromStr for Ratio<T> {
     }
 }
 
+#[cfg(feature = "serde")]
+impl<T> serde::Serialize for Ratio<T>
+    where T: serde::Serialize + Clone + Integer + PartialOrd
+{
+    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where
+        S: serde::Serializer
+    {
+        (self.numer(), self.denom()).serialize(serializer)
+    }
+}
+
+#[cfg(feature = "serde")]
+impl<T> serde::Deserialize for Ratio<T>
+    where T: serde::Deserialize + Clone + Integer + PartialOrd
+{
+    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where
+        D: serde::Deserializer,
+    {
+        let (numer, denom) = try!(serde::Deserialize::deserialize(deserializer));
+        if denom == Zero::zero() {
+            Err(serde::de::Error::invalid_value("denominator is zero"))
+        } else {
+            Ok(Ratio::new_raw(numer, denom))
+        }
+    }
+}
+
 // FIXME: Bubble up specific errors
 #[derive(Copy, Clone, Debug, PartialEq)]
 pub struct ParseRatioError { kind: RatioErrorKind }