direct serialize/deserialize from string/to string

This commit is contained in:
sharks
2018-04-16 19:25:22 -05:00
parent ac3b11b1d7
commit 4414ae4f0f
4 changed files with 75 additions and 6 deletions

View File

@ -2,18 +2,41 @@ use std::fmt;
use std::net::Ipv4Addr;
use std::str::FromStr;
#[cfg(feature = "with-serde")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use common::{cidr_parts, parse_addr, parse_prefix, IpNetworkError};
const IPV4_BITS: u8 = 32;
/// Represents a network range where the IP addresses are of v4
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Ipv4Network {
addr: Ipv4Addr,
prefix: u8,
}
#[cfg(feature = "with-serde")]
impl<'de> Deserialize<'de> for Ipv4Network {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
Ipv4Network::from_str(s).map_err(de::Error::custom)
}
}
#[cfg(feature = "with-serde")]
impl Serialize for Ipv4Network {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
impl Ipv4Network {
/// Constructs a new `Ipv4Network` from any `Ipv4Addr` and a prefix denoting the network size.
/// If the prefix is larger than 32 this will return an `IpNetworkError::InvalidPrefix`.

View File

@ -3,19 +3,42 @@ use std::fmt;
use std::net::Ipv6Addr;
use std::str::FromStr;
#[cfg(feature = "with-serde")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use common::{cidr_parts, parse_prefix, IpNetworkError};
const IPV6_BITS: u8 = 128;
const IPV6_SEGMENT_BITS: u8 = 16;
/// Represents a network range where the IP addresses are of v6
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Ipv6Network {
addr: Ipv6Addr,
prefix: u8,
}
#[cfg(feature = "with-serde")]
impl<'de> Deserialize<'de> for Ipv6Network {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
Ipv6Network::from_str(s).map_err(de::Error::custom)
}
}
#[cfg(feature = "with-serde")]
impl Serialize for Ipv6Network {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
impl Ipv6Network {
/// Constructs a new `Ipv6Network` from any `Ipv6Addr` and a prefix denoting the network size.
/// If the prefix is larger than 128 this will return an `IpNetworkError::InvalidPrefix`.

View File

@ -14,6 +14,9 @@ extern crate serde;
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "with-serde")]
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;
use std::net::IpAddr;
@ -29,13 +32,33 @@ 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.
#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum IpNetwork {
V4(Ipv4Network),
V6(Ipv6Network),
}
#[cfg(feature = "with-serde")]
impl<'de> Deserialize<'de> for IpNetwork {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
IpNetwork::from_str(s).map_err(de::Error::custom)
}
}
#[cfg(feature = "with-serde")]
impl Serialize for IpNetwork {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_string())
}
}
impl IpNetwork {
/// Constructs a new `IpNetwork` from a given `IpAddr` and a prefix denoting the
/// network size. If the prefix is larger than 32 (for IPv4) or 128 (for IPv6), this

View File

@ -17,7 +17,7 @@ mod tests {
#[cfg(feature = "with-serde")]
#[test]
fn test_ipv4_json() {
let json_string = r#"{"ipnetwork":{"addr":"127.1.0.0","prefix":24}}"#;
let json_string = r#"{"ipnetwork":"127.1.0.0/24"}"#;
#[derive(Serialize, Deserialize)]
struct MyStruct {
@ -35,7 +35,7 @@ mod tests {
#[cfg(feature = "with-serde")]
#[test]
fn test_ipv6_json() {
let json_string = r#"{"ipnetwork":{"addr":"::1","prefix":0}}"#;
let json_string = r#"{"ipnetwork":"::1/0"}"#;
#[derive(Serialize, Deserialize)]
struct MyStruct {
@ -56,7 +56,7 @@ mod tests {
#[cfg(feature = "with-serde")]
#[test]
fn test_ipnetwork_json() {
let json_string = r#"{"ipnetwork":[{"V4":{"addr":"127.1.0.0","prefix":24}},{"V6":{"addr":"::1","prefix":0}}]}"#;
let json_string = r#"{"ipnetwork":["127.1.0.0/24","::1/0"]}"#;
#[derive(Serialize, Deserialize)]
struct MyStruct {