Skip to content

Commit

Permalink
Auto merge of serde-rs#171 - erickt:serde, r=hauleth
Browse files Browse the repository at this point in the history
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)`.
  • Loading branch information
homu committed Feb 27, 2016
2 parents 9079b88 + 112923e commit 9b0d4c9
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 1 deletion.
3 changes: 2 additions & 1 deletion Cargo.toml
Expand Up @@ -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
Expand Down
76 changes: 76 additions & 0 deletions src/bigint.rs
Expand Up @@ -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.
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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))]
Expand Down Expand Up @@ -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`.
Expand Down
26 changes: 26 additions & 0 deletions src/complex.rs
Expand Up @@ -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
Expand Down Expand Up @@ -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)]
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Expand Up @@ -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")]
Expand Down
30 changes: 30 additions & 0 deletions src/rational.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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 }
Expand Down

0 comments on commit 9b0d4c9

Please sign in to comment.