Skip to content

Commit 112923e

Browse files
committed
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)`.
1 parent 9079b88 commit 112923e

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)