Skip to content

Commit

Permalink
Implement serde::Serialize and serde::Deserialize.
Browse files Browse the repository at this point in the history
Fixes #37.
  • Loading branch information
radix committed Dec 28, 2017
1 parent 6745365 commit faca99e
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 8 deletions.
1 change: 1 addition & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ build: false
test_script:
- cargo build --verbose
- cargo test --verbose
- cargo test --verbose --features serde

notifications:
- provider: Email
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ before_script: |
script: |
cargo build --verbose &&
(test "$TRAVIS_RUST_VERSION" == "1.20.0" || cargo test --verbose)
(test "$TRAVIS_RUST_VERSION" == "1.20.0" || cargo test --verbose --features serde)
after_success: |
test "$TRAVIS_RUST_VERSION" != "stable" || cargo coveralls
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
### Added
* [#26](https://github.com/iliekturtles/uom/issues/26) Implement `num::Zero`.
* [#35](https://github.com/iliekturtles/uom/issues/35) Implement `num::Saturating`.
* [#37](https://github.com/iliekturtles/uom/issues/35) Implement `serde::Serialize` and
`serde::Deserialize`. Only available when the `serde` feature is enabled.

## [v0.16.0] — 2017-12-21
This release contains significant changes in order to support underlying storage types that
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ maintenance = { status = "actively-developed" }

[dependencies]
num = "0.1"
serde = { version = "1.0", optional = true }
typenum = "1.9.0"

[dev-dependencies]
approx = "0.1.1"
quickcheck = "0.5.0"
serde_json = "1.0"
static_assertions = "0.2.5"

[features]
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ See the [examples](examples) directory for more advanced usage:

## Features
`uom` has multiple `Cargo` features for controlling available underlying storage types, the
inclusion of the pre-built [International System of Units][si] (SI), and `no_std` functionality. The
features are described below. `f32`, `f64`, `std`, and `si` are enabled by default. Features can be
cherry-picked by using the `--no-default-features` and `--features "..."` flags when compiling `uom`
or specifying features in Cargo.toml:
inclusion of the pre-built [International System of Units][si] (SI), support for [Serde][serde],
and `no_std` functionality. The features are described below. `f32`, `f64`, `std`, and `si` are
enabled by default. Features can be cherry-picked by using the `--no-default-features` and
`--features "..."` flags when compiling `uom` or specifying features in Cargo.toml:

```toml
[dependencies]
Expand All @@ -79,6 +79,7 @@ uom = {
"bigint", "biguint", # Arbitrary width integer storage types.
"rational", "rational32", "rational64", "bigrational", # Integer ratio storage types.
"f32", "f64", # Floating point storage types.
"serde", # Serde support.
"si", "std", # Built-in SI system and std library support.
]
}
Expand All @@ -88,12 +89,15 @@ uom = {
`rational`, `rational32`, `rational64`, `bigrational`, `f32`, `f64` -- Features to enable
underlying storage types. At least one of these features must be enabled. `f32` and `f64` are
enabled by default.
* `serde` -- Feature to enable support for serialization and deserialization of quantities with
the [serde][serde] crate. Disabled by default.
* `si` -- Feature to include the pre-built [International System of Units][si] (SI). Enabled by
default.
* `std` -- Feature to compile with standard library support. Disabling this feature compiles `uom`
with `no_std`. Enabled by default.

[si]: http://jcgm.bipm.org/vim/en/1.16.html
[serde]: https://serde.rs/

## Design
Rather than working with [measurement units](http://jcgm.bipm.org/vim/en/1.9.html) (meter,
Expand Down
19 changes: 15 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@
//!
//! ## Features
//! `uom` has multiple `Cargo` features for controlling available underlying storage types, the
//! inclusion of the pre-built [International System of Units][si] (SI), and `no_std` functionality.
//! The features are described below. `f32`, `f64`, `std`, and `si` are enabled by default. Features
//! can be cherry-picked by using the `--no-default-features` and `--features "..."` flags when
//! compiling `uom` or specifying features in Cargo.toml:
//! inclusion of the pre-built [International System of Units][si] (SI), support for
//! [Serde][serde], and `no_std` functionality. The features are described below. `f32`, `f64`,
//! `std`, and `si` are enabled by default. Features can be cherry-picked by using the
//! `--no-default-features` and `--features "..."` flags when compiling `uom` or specifying
//! features in Cargo.toml:
//!
//! ```toml
//! [dependencies]
Expand All @@ -68,6 +69,7 @@
//! "bigint", "biguint", # Arbitrary width integer storage types.
//! "rational", "rational32", "rational64", "bigrational", # Integer ratio storage types.
//! "f32", "f64", # Floating point storage types.
//! "serde", # Serde support.
//! "si", "std", # Built-in SI system and std library support.
//! ]
//! }
Expand All @@ -77,12 +79,15 @@
//! `rational`, `rational32`, `rational64`, `bigrational`, `f32`, `f64` -- Features to enable
//! underlying storage types. At least one of these features must be enabled. `f32` and `f64` are
//! enabled by default.
//! * `serde` -- Feature to enable support for serialization and deserialization of quantities with
//! the [serde][serde] crate. Disabled by default.
//! * `si` -- Feature to include the pre-built [International System of Units][si] (SI). Enabled by
//! default.
//! * `std` -- Feature to compile with standard library support. Disabling this feature compiles
//! `uom` with `no_std`. Enabled by default.
//!
//! [si]: http://jcgm.bipm.org/vim/en/1.16.html
//! [serde]: https://serde.rs/
//!
//! ## Design
//! Rather than working with [measurement units](http://jcgm.bipm.org/vim/en/1.9.html) (meter,
Expand Down Expand Up @@ -156,6 +161,10 @@ compile_error!("A least one underlying storage type must be enabled. See the fea
#[doc(hidden)]
pub extern crate num;

#[doc(hidden)]
#[cfg(feature = "serde")]
pub extern crate serde;

#[doc(hidden)]
pub extern crate typenum;

Expand All @@ -165,6 +174,8 @@ extern crate approx;
#[cfg(test)]
#[macro_use]
extern crate quickcheck;
#[cfg(all(test, feature = "serde"))]
extern crate serde_json;
#[cfg(test)]
#[macro_use]
extern crate static_assertions;
Expand Down
36 changes: 36 additions & 0 deletions src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,42 @@ macro_rules! system {
}
}

#[cfg(feature = "serde")]
impl<D, U, V> $crate::serde::Serialize for Quantity<D, U, V>
where
D: Dimension + ?Sized,
U: Units<V> + ?Sized,
V: $crate::num::Num + $crate::Conversion<V> + $crate::serde::Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: $crate::serde::Serializer
{
self.value.serialize(serializer)
}
}

#[cfg(feature = "serde")]
impl<'de, D, U, V> $crate::serde::Deserialize<'de> for Quantity<D, U, V>
where
D: Dimension + ?Sized,
U: Units<V> + ?Sized,
V: $crate::num::Num + $crate::Conversion<V> + $crate::serde::Deserialize<'de>,
{
fn deserialize<De>(deserializer: De) -> Result<Self, De::Error>
where
De: $crate::serde::Deserializer<'de>,
{
let value: V = $crate::serde::Deserialize::deserialize(deserializer)?;

Ok(Quantity {
dimension: $crate::lib::marker::PhantomData,
units: $crate::lib::marker::PhantomData,
value,
})
}
}

/// Macro to implement [`quantity`](si/struct.Quantity.html) type aliases for a specific
/// [system of units][units] and value storage type.
///
Expand Down
22 changes: 22 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use num::{Float, FromPrimitive, One, Saturating, Signed, Zero};
use quickcheck::TestResult;
use lib::fmt::Debug;
use lib::marker::PhantomData;
#[cfg(all(feature = "serde"))]
use serde_json;
#[allow(unused_imports)]
use typenum::{N1, P1, P2, P3, Z0};

Expand Down Expand Up @@ -527,6 +529,26 @@ mod system_macro {
&(Length::new::<meter>((*l).clone())
% Length::new::<meter>((*r).clone())).get(meter)))
}

#[cfg(feature = "serde")]
#[allow(trivial_casts)]
fn serde_serialize(v: A<V>) -> bool {
let m = Length::new::<meter>((*v).clone());
let json_f = serde_json::to_string(&*v).expect("Must be able to serialize num");
let json_q = serde_json::to_string(&m).expect("Must be able to serialize Quantity");

json_f == json_q
}

#[cfg(feature = "serde")]
#[allow(trivial_casts)]
fn serde_deserialize(v: A<V>) -> bool {
let json_f = serde_json::to_string(&*v).expect("Must be able to serialize num");
let length: Length = serde_json::from_str(&json_f)
.expect("Must be able to deserialize Quantity");

Test::approx_eq(&*v, &length.get(meter))
}
}
}

Expand Down

0 comments on commit faca99e

Please sign in to comment.