diff --git a/Cargo.toml b/Cargo.toml index e58a638..b5b6b95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,10 +13,10 @@ categories = ["network-programming", "os"] [dependencies] clippy = {version = "0.0.302", optional = true} serde = ">=0.8.0, <2.0" -serde_derive = ">=0.8.0, <2.0" [dev-dependencies] serde_json = "1.0" +serde_derive = ">=0.8.0, <2.0" [badges] travis-ci = { repository = "achanda/ipnetwork" } diff --git a/src/lib.rs b/src/lib.rs index 3d1a348..2c5fe49 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,8 +7,6 @@ #![doc(html_root_url = "https://docs.rs/ipnetwork/0.13.1")] extern crate serde; -#[macro_use] -extern crate serde_derive; use std::fmt; use std::net::IpAddr; @@ -19,19 +17,38 @@ mod ipv6; use std::str::FromStr; +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; + pub use common::IpNetworkError; -pub use ipv4::{Ipv4Network, ipv4_mask_to_prefix}; -pub use ipv6::{Ipv6Network, ipv6_mask_to_prefix}; +pub use ipv4::{ipv4_mask_to_prefix, Ipv4Network}; +pub use ipv6::{ipv6_mask_to_prefix, Ipv6Network}; /// Represents a generic network range. This type can have two variants: /// the v4 and the v6 case. -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] -#[serde(untagged)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub enum IpNetwork { V4(Ipv4Network), V6(Ipv6Network), } +impl<'de> Deserialize<'de> for IpNetwork { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = ::deserialize(deserializer)?; + IpNetwork::from_str(&s).map_err(de::Error::custom) + } +} + +impl Serialize for IpNetwork { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} /// Represents a generic network size. For IPv4, the max size is a u32 and for IPv6, it is a u128 #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] @@ -79,7 +96,7 @@ impl IpNetwork { } } - /// Returns the address of the network denoted by this `IpNetwork`. + /// Returns the address of the network denoted by this `IpNetwork`. /// This means the lowest possible IP address inside of the network. /// /// # Examples @@ -207,7 +224,6 @@ impl IpNetwork { } } - /// Returns the number of possible host addresses in this `IpAddr` /// /// # Examples @@ -292,3 +308,15 @@ pub fn ip_mask_to_prefix(mask: IpAddr) -> Result { IpAddr::V6(mask) => ipv6_mask_to_prefix(mask), } } + +#[cfg(test)] +mod test { + #[test] + fn deserialize_from_serde_json_value() { + use super::*; + let network = IpNetwork::from_str("0.0.0.0/0").unwrap(); + let val: serde_json::value::Value = serde_json::from_str(&serde_json::to_string(&network).unwrap()).unwrap(); + let _deser: IpNetwork = + serde_json::from_value(val).expect("Fails to deserialize from json_value::value::Value"); + } +}