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]
|
[dependencies]
|
||||||
rustc-serialize = { version = "0.3.13", optional = true }
|
|
||||||
rand = { version = "0.3.8", 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]
|
[dev-dependencies]
|
||||||
# Some tests of non-rand functionality still use rand because the tests
|
# 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::{u8, i64, u64};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
use serde;
|
||||||
|
|
||||||
// Some of the tests of non-RNG-based functionality are randomized using the
|
// 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
|
// RNG-based functionality, so the RNG-based functionality needs to be enabled
|
||||||
// for tests.
|
// 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
|
// `DoubleBigDigit` size dependent
|
||||||
/// Returns the greatest power of the radix <= big_digit::BASE
|
/// Returns the greatest power of the radix <= big_digit::BASE
|
||||||
#[inline]
|
#[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.
|
/// A big signed integer type.
|
||||||
#[derive(Clone, Debug, Hash)]
|
#[derive(Clone, Debug, Hash)]
|
||||||
#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
|
#[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`.
|
/// A generic trait for converting a value to a `BigInt`.
|
||||||
pub trait ToBigInt {
|
pub trait ToBigInt {
|
||||||
/// Converts the value of `self` to a `BigInt`.
|
/// Converts the value of `self` to a `BigInt`.
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Add, Div, Mul, Neg, Sub};
|
use std::ops::{Add, Div, Mul, Neg, Sub};
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
use serde;
|
||||||
|
|
||||||
use {Zero, One, Num, Float};
|
use {Zero, One, Num, Float};
|
||||||
|
|
||||||
// FIXME #1284: handle complex NaN & infinity etc. This
|
// 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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
|
@ -66,6 +66,9 @@ extern crate rustc_serialize;
|
||||||
#[cfg(any(feature = "rand", all(feature = "bigint", test)))]
|
#[cfg(any(feature = "rand", all(feature = "bigint", test)))]
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
extern crate serde;
|
||||||
|
|
||||||
#[cfg(feature = "bigint")]
|
#[cfg(feature = "bigint")]
|
||||||
pub use bigint::{BigInt, BigUint};
|
pub use bigint::{BigInt, BigUint};
|
||||||
#[cfg(feature = "rational")]
|
#[cfg(feature = "rational")]
|
||||||
|
|
|
@ -18,6 +18,9 @@ use std::fmt;
|
||||||
use std::ops::{Add, Div, Mul, Neg, Rem, Sub};
|
use std::ops::{Add, Div, Mul, Neg, Rem, Sub};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
use serde;
|
||||||
|
|
||||||
#[cfg(feature = "bigint")]
|
#[cfg(feature = "bigint")]
|
||||||
use bigint::{BigInt, BigUint, Sign};
|
use bigint::{BigInt, BigUint, Sign};
|
||||||
use traits::{FromPrimitive, Float, PrimInt};
|
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
|
// FIXME: Bubble up specific errors
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub struct ParseRatioError { kind: RatioErrorKind }
|
pub struct ParseRatioError { kind: RatioErrorKind }
|
||||||
|
|
Loading…
Reference in New Issue