diff --git a/serde/Cargo.toml b/serde/Cargo.toml index 7474aaae..0a6c1ca0 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -11,3 +11,7 @@ keywords = ["serialization"] [dependencies] num = "*" + +[features] +nightly = [] + diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 3f6cbf80..082fcdf7 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -9,6 +9,11 @@ use std::sync::Arc; use num::FromPrimitive; +#[cfg(feature = "nightly")] +use core::nonzero::{NonZero, Zeroable}; +#[cfg(feature = "nightly")] +use std::num::Zero; + use de::{ Deserialize, Deserializer, @@ -865,3 +870,18 @@ impl<'a, T: ?Sized> Deserialize for Cow<'a, T> where T: ToOwned, T::Owned: Deser Ok(Cow::Owned(val)) } } + +/////////////////////////////////////////////////////////////////////////////// + +impl Deserialize for NonZero where T: Deserialize + PartialEq + Zeroable + Zero { + fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer { + let value = try!(Deserialize::deserialize(deserializer)); + if value == Zero::zero() { + return Err(Error::syntax_error()) + } + unsafe { + Ok(NonZero::new(value)) + } + } +} + diff --git a/serde/src/lib.rs b/serde/src/lib.rs index 9c31fc55..70d0b00a 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -6,9 +6,13 @@ //! leaving serde to perform roughly the same speed as a hand written serializer for a specific //! type. #![doc(html_root_url="http://erickt.github.io/rust-serde")] +#![cfg_attr(feature = "nightly", feature(core, nonzero, zero_one))] extern crate num; +#[cfg(feature = "nightly")] +extern crate core; + pub use ser::{Serialize, Serializer}; pub use de::{Deserialize, Deserializer, Error}; diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 88183654..3a44a866 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -5,6 +5,9 @@ use std::path; use std::rc::Rc; use std::sync::Arc; +#[cfg(feature = "nightly")] +use core::nonzero::{NonZero, Zeroable}; + use super::{ Serialize, Serializer, @@ -545,3 +548,10 @@ impl Serialize for path::PathBuf { self.to_str().unwrap().serialize(serializer) } } + +impl Serialize for NonZero where T: Serialize + Zeroable { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { + (**self).serialize(serializer) + } +} +