Parse Ipv4Addr using Ipv4Addr::from_str
This commit is contained in:
Abhishek Chanda
2018-05-30 19:01:38 +02:00
committed by GitHub
3 changed files with 5 additions and 60 deletions

View File

@ -56,20 +56,3 @@ pub fn parse_prefix(prefix: &str, max: u8) -> Result<u8, IpNetworkError> {
Ok(mask) Ok(mask)
} }
} }
pub fn parse_addr(addr: &str) -> Result<Ipv4Addr, IpNetworkError> {
let addr_parts = addr.split('.').map(|b| b.parse::<u8>());
let mut bytes = [0; 4];
for (i, byte) in addr_parts.enumerate() {
if i >= 4 {
return Err(IpNetworkError::InvalidAddr(format!(
"More than 4 bytes: {}",
addr
)));
}
bytes[i] = byte.map_err(|_| {
IpNetworkError::InvalidAddr(format!("All bytes not 0-255: {}", addr))
})?;
}
Ok(Ipv4Addr::new(bytes[0], bytes[1], bytes[2], bytes[3]))
}

View File

@ -4,7 +4,7 @@ use std::str::FromStr;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use common::{cidr_parts, parse_addr, parse_prefix, IpNetworkError}; use common::{cidr_parts, parse_prefix, IpNetworkError};
const IPV4_BITS: u8 = 32; const IPV4_BITS: u8 = 32;
@ -205,7 +205,8 @@ impl FromStr for Ipv4Network {
type Err = IpNetworkError; type Err = IpNetworkError;
fn from_str(s: &str) -> Result<Ipv4Network, IpNetworkError> { fn from_str(s: &str) -> Result<Ipv4Network, IpNetworkError> {
let (addr_str, prefix_str) = cidr_parts(s)?; let (addr_str, prefix_str) = cidr_parts(s)?;
let addr = parse_addr(addr_str)?; let addr = Ipv4Addr::from_str(addr_str)
.map_err(|_| IpNetworkError::InvalidAddr(addr_str.to_string()))?;
let prefix = match prefix_str { let prefix = match prefix_str {
Some(v) => parse_prefix(v, IPV4_BITS)?, Some(v) => parse_prefix(v, IPV4_BITS)?,
None => IPV4_BITS, None => IPV4_BITS,
@ -274,13 +275,6 @@ mod test {
assert!(net.is_err()); assert!(net.is_err());
} }
#[test]
fn parse_v4_0bit() {
let cidr: Ipv4Network = "0/0".parse().unwrap();
assert_eq!(cidr.ip(), Ipv4Addr::new(0, 0, 0, 0));
assert_eq!(cidr.prefix(), 0);
}
#[test] #[test]
fn parse_v4_24bit() { fn parse_v4_24bit() {
let cidr: Ipv4Network = "127.1.0.0/24".parse().unwrap(); let cidr: Ipv4Network = "127.1.0.0/24".parse().unwrap();
@ -339,30 +333,6 @@ mod test {
assert_eq!(None, cidr); assert_eq!(None, cidr);
} }
#[test]
fn size_v4_24bit() {
let net: Ipv4Network = "0/24".parse().unwrap();
assert_eq!(net.size(), 256);
}
#[test]
fn size_v4_1bit() {
let net: Ipv4Network = "0/31".parse().unwrap();
assert_eq!(net.size(), 2);
}
#[test]
fn size_v4_max() {
let net: Ipv4Network = "0/0".parse().unwrap();
assert_eq!(net.size(), 4_294_967_296);
}
#[test]
fn size_v4_min() {
let net: Ipv4Network = "0/32".parse().unwrap();
assert_eq!(net.size(), 1);
}
#[test] #[test]
fn nth_v4() { fn nth_v4() {
let net = Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 0), 24).unwrap(); let net = Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 0), 24).unwrap();
@ -439,14 +409,6 @@ mod test {
assert_eq!(None, iter.next()); assert_eq!(None, iter.next());
} }
#[test]
fn iterator_v4_tiny() {
let cidr: Ipv4Network = "10/32".parse().unwrap();
let mut iter = cidr.iter();
assert_eq!(Ipv4Addr::new(10, 0, 0, 0), iter.next().unwrap());
assert_eq!(None, iter.next());
}
// Tests the entire IPv4 space to see if the iterator will stop at the correct place // Tests the entire IPv4 space to see if the iterator will stop at the correct place
// and not overflow or wrap around. Ignored since it takes a long time to run. // and not overflow or wrap around. Ignored since it takes a long time to run.
#[test] #[test]

View File

@ -20,8 +20,8 @@ mod ipv6;
use std::str::FromStr; use std::str::FromStr;
pub use common::IpNetworkError; pub use common::IpNetworkError;
pub use ipv4::{ipv4_mask_to_prefix, Ipv4Network}; pub use ipv4::{Ipv4Network, ipv4_mask_to_prefix};
pub use ipv6::{ipv6_mask_to_prefix, Ipv6Network}; pub use ipv6::{Ipv6Network, ipv6_mask_to_prefix};
/// Represents a generic network range. This type can have two variants: /// Represents a generic network range. This type can have two variants:
/// the v4 and the v6 case. /// the v4 and the v6 case.