mirror of
https://github.com/achanda/ipnetwork.git
synced 2025-06-16 08:48:51 +00:00
Merge pull request #79 from sharksforarms/issue-#62
Parse Ipv4Addr using Ipv4Addr::from_str
This commit is contained in:
@ -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]))
|
|
||||||
}
|
|
||||||
|
44
src/ipv4.rs
44
src/ipv4.rs
@ -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]
|
||||||
|
@ -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.
|
||||||
|
Reference in New Issue
Block a user