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)`.
This commit is contained in:
commit
9b0d4c91cb
|
@ -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
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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 }
|
||||
|
|
Loading…
Reference in New Issue