diff --git a/src/common.rs b/src/common.rs index 943894d..7016990 100644 --- a/src/common.rs +++ b/src/common.rs @@ -3,7 +3,7 @@ use std::fmt; use std::error::Error; /// Represents a bunch of errors that can occur while working with a `IpNetwork` -#[derive(Debug,Clone,PartialEq,Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum IpNetworkError { InvalidAddr(String), InvalidPrefix, @@ -29,23 +29,30 @@ impl Error for IpNetworkError { InvalidPrefix => "prefix is invalid", InvalidCidrFormat(_) => "cidr is invalid", } - } } pub fn cidr_parts(cidr: &str) -> Result<(&str, &str), IpNetworkError> { let parts = cidr.split('/').collect::>(); if parts.len() == 1 { - Err(IpNetworkError::InvalidCidrFormat(format!("CIDR must contain '/': {}", cidr))) + Err(IpNetworkError::InvalidCidrFormat(format!( + "CIDR must contain '/': {}", + cidr + ))) } else if parts.len() == 2 { Ok((parts[0], parts[1])) } else { - Err(IpNetworkError::InvalidCidrFormat(format!("CIDR must contain a single '/': {}", cidr))) + Err(IpNetworkError::InvalidCidrFormat(format!( + "CIDR must contain a single '/': {}", + cidr + ))) } } pub fn parse_prefix(prefix: &str, max: u8) -> Result { - let mask = prefix.parse::().map_err(|_| IpNetworkError::InvalidPrefix)?; + let mask = prefix + .parse::() + .map_err(|_| IpNetworkError::InvalidPrefix)?; if mask > max { Err(IpNetworkError::InvalidPrefix) } else { @@ -58,11 +65,14 @@ pub fn parse_addr(addr: &str) -> Result { 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))); + return Err(IpNetworkError::InvalidAddr(format!( + "More than 4 bytes: {}", + addr + ))); } bytes[i] = byte.map_err(|_| { - IpNetworkError::InvalidAddr(format!("All bytes not 0-255: {}", addr)) - })?; + IpNetworkError::InvalidAddr(format!("All bytes not 0-255: {}", addr)) + })?; } Ok(Ipv4Addr::new(bytes[0], bytes[1], bytes[2], bytes[3])) } diff --git a/src/ipv4.rs b/src/ipv4.rs index f57b2f0..38bc6ae 100644 --- a/src/ipv4.rs +++ b/src/ipv4.rs @@ -2,12 +2,12 @@ use std::fmt; use std::net::Ipv4Addr; use std::str::FromStr; -use common::{IpNetworkError, cidr_parts, parse_prefix, parse_addr}; +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 -#[derive(Debug,Clone,Copy,Hash,PartialEq,Eq,PartialOrd,Ord)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Ipv4Network { addr: Ipv4Addr, prefix: u8, @@ -171,7 +171,6 @@ impl fmt::Display for Ipv4Network { } } - /// Creates an `Ipv4Network` from parsing a string in CIDR notation. /// /// # Examples @@ -195,7 +194,6 @@ impl FromStr for Ipv4Network { } } - impl From for Ipv4Network { fn from(a: Ipv4Addr) -> Ipv4Network { Ipv4Network { diff --git a/src/ipv6.rs b/src/ipv6.rs index 3ed3833..5fe9ed1 100644 --- a/src/ipv6.rs +++ b/src/ipv6.rs @@ -3,13 +3,13 @@ use std::fmt; use std::net::Ipv6Addr; use std::str::FromStr; -use common::{IpNetworkError, cidr_parts, parse_prefix}; +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 -#[derive(Debug,Clone,Copy,Hash,PartialEq,Eq,PartialOrd,Ord)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Ipv6Network { addr: Ipv6Addr, prefix: u8, @@ -34,7 +34,6 @@ impl Ipv6Network { /// addresses. #[cfg(feature = "ipv6-iterator")] pub fn iter(&self) -> Ipv6NetworkIterator { - let dec = u128::from(self.addr); let max = u128::max_value(); let prefix = self.prefix; @@ -45,11 +44,10 @@ impl Ipv6Network { let mask = max.checked_shr(prefix as u32).unwrap_or(0); let end: u128 = dec | mask; - Ipv6NetworkIterator{ + Ipv6NetworkIterator { next: start, end: end, } - } /// Returns the address of the network denoted by this `Ipv6Network`. @@ -137,10 +135,13 @@ impl Ipv6Network { let a = self.addr.segments(); let b = ip.segments(); let addrs = Iterator::zip(a.iter(), b.iter()); - self.mask().segments().iter().zip(addrs).all(|(mask, (a, b))| a & mask == b & mask) + self.mask() + .segments() + .iter() + .zip(addrs) + .all(|(mask, (a, b))| a & mask == b & mask) } - /// Returns number of possible host addresses in this `Ipv6Network`. /// /// # Examples @@ -166,7 +167,8 @@ impl FromStr for Ipv6Network { type Err = IpNetworkError; fn from_str(s: &str) -> Result { let (addr_str, prefix_str) = cidr_parts(s)?; - let addr = Ipv6Addr::from_str(addr_str).map_err(|_| IpNetworkError::InvalidAddr(addr_str.to_string()))?; + let addr = Ipv6Addr::from_str(addr_str) + .map_err(|_| IpNetworkError::InvalidAddr(addr_str.to_string()))?; let prefix = parse_prefix(prefix_str, IPV6_BITS)?; Ipv6Network::new(addr, prefix) } @@ -192,19 +194,13 @@ impl Iterator for Ipv6NetworkIterator { type Item = Ipv6Addr; fn next(&mut self) -> Option { - if self.next <= self.end { - let next = Ipv6Addr::from(self.next); self.next += 1; Some(next) - } else { - None - } - } } @@ -338,10 +334,22 @@ mod test { fn iterator_v6() { let cidr: Ipv6Network = "2001:db8::/126".parse().unwrap(); let mut iter = cidr.iter(); - assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0), iter.next().unwrap()); - assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), iter.next().unwrap()); - assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 2), iter.next().unwrap()); - assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 3), iter.next().unwrap()); + assert_eq!( + Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0), + iter.next().unwrap() + ); + assert_eq!( + Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), + iter.next().unwrap() + ); + assert_eq!( + Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 2), + iter.next().unwrap() + ); + assert_eq!( + Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 3), + iter.next().unwrap() + ); assert_eq!(None, iter.next()); } @@ -350,7 +358,10 @@ mod test { fn iterator_v6_tiny() { let cidr: Ipv6Network = "2001:db8::/128".parse().unwrap(); let mut iter = cidr.iter(); - assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0), iter.next().unwrap()); + assert_eq!( + Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0), + iter.next().unwrap() + ); assert_eq!(None, iter.next()); } diff --git a/src/lib.rs b/src/lib.rs index e674332..37f3c17 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,7 @@ pub use common::IpNetworkError; /// 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)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub enum IpNetwork { V4(Ipv4Network), V6(Ipv6Network),