Skip to content

Commit 9b0d4c9

Browse files
committed
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)`.
2 parents 9079b88 + 112923e commit 9b0d4c9

File tree

5 files changed

+137
-1
lines changed

5 files changed

+137
-1
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ complex, rational, range iterators, generic integers, and more!
1414
"""
1515

1616
[dependencies]
17-
rustc-serialize = { version = "0.3.13", optional = true }
1817
rand = { version = "0.3.8", optional = true }
18+
rustc-serialize = { version = "0.3.13", optional = true }
19+
serde = { version = "^0.7.0", optional = true }
1920

2021
[dev-dependencies]
2122
# Some tests of non-rand functionality still use rand because the tests

src/bigint.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ use std::{f32, f64};
7979
use std::{u8, i64, u64};
8080
use std::ascii::AsciiExt;
8181

82+
#[cfg(feature = "serde")]
83+
use serde;
84+
8285
// Some of the tests of non-RNG-based functionality are randomized using the
8386
// RNG-based functionality, so the RNG-based functionality needs to be enabled
8487
// for tests.
@@ -1723,6 +1726,27 @@ impl BigUint {
17231726
}
17241727
}
17251728

1729+
#[cfg(feature = "serde")]
1730+
impl serde::Serialize for BigUint {
1731+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where
1732+
S: serde::Serializer
1733+
{
1734+
self.data.serialize(serializer)
1735+
}
1736+
}
1737+
1738+
#[cfg(feature = "serde")]
1739+
impl serde::Deserialize for BigUint {
1740+
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where
1741+
D: serde::Deserializer,
1742+
{
1743+
let data = try!(Vec::deserialize(deserializer));
1744+
Ok(BigUint {
1745+
data: data,
1746+
})
1747+
}
1748+
}
1749+
17261750
// `DoubleBigDigit` size dependent
17271751
/// Returns the greatest power of the radix <= big_digit::BASE
17281752
#[inline]
@@ -1809,6 +1833,36 @@ impl Mul<Sign> for Sign {
18091833
}
18101834
}
18111835

1836+
#[cfg(feature = "serde")]
1837+
impl serde::Serialize for Sign {
1838+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where
1839+
S: serde::Serializer
1840+
{
1841+
match *self {
1842+
Sign::Minus => (-1i8).serialize(serializer),
1843+
Sign::NoSign => 0i8.serialize(serializer),
1844+
Sign::Plus => 1i8.serialize(serializer),
1845+
}
1846+
}
1847+
}
1848+
1849+
#[cfg(feature = "serde")]
1850+
impl serde::Deserialize for Sign {
1851+
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where
1852+
D: serde::Deserializer,
1853+
{
1854+
use serde::de::Error;
1855+
1856+
let sign: i8 = try!(serde::Deserialize::deserialize(deserializer));
1857+
match sign {
1858+
-1 => Ok(Sign::Minus),
1859+
0 => Ok(Sign::NoSign),
1860+
1 => Ok(Sign::Plus),
1861+
_ => Err(D::Error::invalid_value("sign must be -1, 0, or 1")),
1862+
}
1863+
}
1864+
}
1865+
18121866
/// A big signed integer type.
18131867
#[derive(Clone, Debug, Hash)]
18141868
#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
@@ -2398,6 +2452,28 @@ impl From<BigUint> for BigInt {
23982452
}
23992453
}
24002454

2455+
#[cfg(feature = "serde")]
2456+
impl serde::Serialize for BigInt {
2457+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where
2458+
S: serde::Serializer
2459+
{
2460+
(self.sign, &self.data).serialize(serializer)
2461+
}
2462+
}
2463+
2464+
#[cfg(feature = "serde")]
2465+
impl serde::Deserialize for BigInt {
2466+
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where
2467+
D: serde::Deserializer,
2468+
{
2469+
let (sign, data) = try!(serde::Deserialize::deserialize(deserializer));
2470+
Ok(BigInt {
2471+
sign: sign,
2472+
data: data,
2473+
})
2474+
}
2475+
}
2476+
24012477
/// A generic trait for converting a value to a `BigInt`.
24022478
pub trait ToBigInt {
24032479
/// Converts the value of `self` to a `BigInt`.

src/complex.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
use std::fmt;
1515
use std::ops::{Add, Div, Mul, Neg, Sub};
1616

17+
#[cfg(feature = "serde")]
18+
use serde;
19+
1720
use {Zero, One, Num, Float};
1821

1922
// FIXME #1284: handle complex NaN & infinity etc. This
@@ -567,6 +570,29 @@ impl<T> fmt::Display for Complex<T> where
567570
}
568571
}
569572

573+
#[cfg(feature = "serde")]
574+
impl<T> serde::Serialize for Complex<T>
575+
where T: serde::Serialize
576+
{
577+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where
578+
S: serde::Serializer
579+
{
580+
(&self.re, &self.im).serialize(serializer)
581+
}
582+
}
583+
584+
#[cfg(feature = "serde")]
585+
impl<T> serde::Deserialize for Complex<T> where
586+
T: serde::Deserialize + Num + Clone
587+
{
588+
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where
589+
D: serde::Deserializer,
590+
{
591+
let (re, im) = try!(serde::Deserialize::deserialize(deserializer));
592+
Ok(Complex::new(re, im))
593+
}
594+
}
595+
570596
#[cfg(test)]
571597
mod test {
572598
#![allow(non_upper_case_globals)]

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ extern crate rustc_serialize;
6666
#[cfg(any(feature = "rand", all(feature = "bigint", test)))]
6767
extern crate rand;
6868

69+
#[cfg(feature = "serde")]
70+
extern crate serde;
71+
6972
#[cfg(feature = "bigint")]
7073
pub use bigint::{BigInt, BigUint};
7174
#[cfg(feature = "rational")]

src/rational.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ use std::fmt;
1818
use std::ops::{Add, Div, Mul, Neg, Rem, Sub};
1919
use std::str::FromStr;
2020

21+
#[cfg(feature = "serde")]
22+
use serde;
23+
2124
#[cfg(feature = "bigint")]
2225
use bigint::{BigInt, BigUint, Sign};
2326
use traits::{FromPrimitive, Float, PrimInt};
@@ -528,6 +531,33 @@ impl<T: FromStr + Clone + Integer> FromStr for Ratio<T> {
528531
}
529532
}
530533

534+
#[cfg(feature = "serde")]
535+
impl<T> serde::Serialize for Ratio<T>
536+
where T: serde::Serialize + Clone + Integer + PartialOrd
537+
{
538+
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where
539+
S: serde::Serializer
540+
{
541+
(self.numer(), self.denom()).serialize(serializer)
542+
}
543+
}
544+
545+
#[cfg(feature = "serde")]
546+
impl<T> serde::Deserialize for Ratio<T>
547+
where T: serde::Deserialize + Clone + Integer + PartialOrd
548+
{
549+
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where
550+
D: serde::Deserializer,
551+
{
552+
let (numer, denom) = try!(serde::Deserialize::deserialize(deserializer));
553+
if denom == Zero::zero() {
554+
Err(serde::de::Error::invalid_value("denominator is zero"))
555+
} else {
556+
Ok(Ratio::new_raw(numer, denom))
557+
}
558+
}
559+
}
560+
531561
// FIXME: Bubble up specific errors
532562
#[derive(Copy, Clone, Debug, PartialEq)]
533563
pub struct ParseRatioError { kind: RatioErrorKind }

0 commit comments

Comments
 (0)