mirror of
https://github.com/achanda/ipnetwork.git
synced 2025-06-16 16:58:50 +00:00
Another round of formatting
This commit is contained in:
@ -3,7 +3,7 @@ use std::fmt;
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
/// Represents a bunch of errors that can occur while working with a `IpNetwork`
|
/// 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 {
|
pub enum IpNetworkError {
|
||||||
InvalidAddr(String),
|
InvalidAddr(String),
|
||||||
InvalidPrefix,
|
InvalidPrefix,
|
||||||
@ -29,23 +29,30 @@ impl Error for IpNetworkError {
|
|||||||
InvalidPrefix => "prefix is invalid",
|
InvalidPrefix => "prefix is invalid",
|
||||||
InvalidCidrFormat(_) => "cidr is invalid",
|
InvalidCidrFormat(_) => "cidr is invalid",
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cidr_parts(cidr: &str) -> Result<(&str, &str), IpNetworkError> {
|
pub fn cidr_parts(cidr: &str) -> Result<(&str, &str), IpNetworkError> {
|
||||||
let parts = cidr.split('/').collect::<Vec<&str>>();
|
let parts = cidr.split('/').collect::<Vec<&str>>();
|
||||||
if parts.len() == 1 {
|
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 {
|
} else if parts.len() == 2 {
|
||||||
Ok((parts[0], parts[1]))
|
Ok((parts[0], parts[1]))
|
||||||
} else {
|
} 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<u8, IpNetworkError> {
|
pub fn parse_prefix(prefix: &str, max: u8) -> Result<u8, IpNetworkError> {
|
||||||
let mask = prefix.parse::<u8>().map_err(|_| IpNetworkError::InvalidPrefix)?;
|
let mask = prefix
|
||||||
|
.parse::<u8>()
|
||||||
|
.map_err(|_| IpNetworkError::InvalidPrefix)?;
|
||||||
if mask > max {
|
if mask > max {
|
||||||
Err(IpNetworkError::InvalidPrefix)
|
Err(IpNetworkError::InvalidPrefix)
|
||||||
} else {
|
} else {
|
||||||
@ -58,11 +65,14 @@ pub fn parse_addr(addr: &str) -> Result<Ipv4Addr, IpNetworkError> {
|
|||||||
let mut bytes = [0; 4];
|
let mut bytes = [0; 4];
|
||||||
for (i, byte) in addr_parts.enumerate() {
|
for (i, byte) in addr_parts.enumerate() {
|
||||||
if i >= 4 {
|
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(|_| {
|
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]))
|
Ok(Ipv4Addr::new(bytes[0], bytes[1], bytes[2], bytes[3]))
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,12 @@ use std::fmt;
|
|||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::str::FromStr;
|
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;
|
const IPV4_BITS: u8 = 32;
|
||||||
|
|
||||||
/// Represents a network range where the IP addresses are of v4
|
/// 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 {
|
pub struct Ipv4Network {
|
||||||
addr: Ipv4Addr,
|
addr: Ipv4Addr,
|
||||||
prefix: u8,
|
prefix: u8,
|
||||||
@ -171,7 +171,6 @@ impl fmt::Display for Ipv4Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Creates an `Ipv4Network` from parsing a string in CIDR notation.
|
/// Creates an `Ipv4Network` from parsing a string in CIDR notation.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
@ -195,7 +194,6 @@ impl FromStr for Ipv4Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl From<Ipv4Addr> for Ipv4Network {
|
impl From<Ipv4Addr> for Ipv4Network {
|
||||||
fn from(a: Ipv4Addr) -> Ipv4Network {
|
fn from(a: Ipv4Addr) -> Ipv4Network {
|
||||||
Ipv4Network {
|
Ipv4Network {
|
||||||
|
49
src/ipv6.rs
49
src/ipv6.rs
@ -3,13 +3,13 @@ use std::fmt;
|
|||||||
use std::net::Ipv6Addr;
|
use std::net::Ipv6Addr;
|
||||||
use std::str::FromStr;
|
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_BITS: u8 = 128;
|
||||||
const IPV6_SEGMENT_BITS: u8 = 16;
|
const IPV6_SEGMENT_BITS: u8 = 16;
|
||||||
|
|
||||||
/// Represents a network range where the IP addresses are of v6
|
/// 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 {
|
pub struct Ipv6Network {
|
||||||
addr: Ipv6Addr,
|
addr: Ipv6Addr,
|
||||||
prefix: u8,
|
prefix: u8,
|
||||||
@ -34,7 +34,6 @@ impl Ipv6Network {
|
|||||||
/// addresses.
|
/// addresses.
|
||||||
#[cfg(feature = "ipv6-iterator")]
|
#[cfg(feature = "ipv6-iterator")]
|
||||||
pub fn iter(&self) -> Ipv6NetworkIterator {
|
pub fn iter(&self) -> Ipv6NetworkIterator {
|
||||||
|
|
||||||
let dec = u128::from(self.addr);
|
let dec = u128::from(self.addr);
|
||||||
let max = u128::max_value();
|
let max = u128::max_value();
|
||||||
let prefix = self.prefix;
|
let prefix = self.prefix;
|
||||||
@ -45,11 +44,10 @@ impl Ipv6Network {
|
|||||||
let mask = max.checked_shr(prefix as u32).unwrap_or(0);
|
let mask = max.checked_shr(prefix as u32).unwrap_or(0);
|
||||||
let end: u128 = dec | mask;
|
let end: u128 = dec | mask;
|
||||||
|
|
||||||
Ipv6NetworkIterator{
|
Ipv6NetworkIterator {
|
||||||
next: start,
|
next: start,
|
||||||
end: end,
|
end: end,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the address of the network denoted by this `Ipv6Network`.
|
/// Returns the address of the network denoted by this `Ipv6Network`.
|
||||||
@ -137,10 +135,13 @@ impl Ipv6Network {
|
|||||||
let a = self.addr.segments();
|
let a = self.addr.segments();
|
||||||
let b = ip.segments();
|
let b = ip.segments();
|
||||||
let addrs = Iterator::zip(a.iter(), b.iter());
|
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`.
|
/// Returns number of possible host addresses in this `Ipv6Network`.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
@ -166,7 +167,8 @@ impl FromStr for Ipv6Network {
|
|||||||
type Err = IpNetworkError;
|
type Err = IpNetworkError;
|
||||||
fn from_str(s: &str) -> Result<Ipv6Network, IpNetworkError> {
|
fn from_str(s: &str) -> Result<Ipv6Network, IpNetworkError> {
|
||||||
let (addr_str, prefix_str) = cidr_parts(s)?;
|
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)?;
|
let prefix = parse_prefix(prefix_str, IPV6_BITS)?;
|
||||||
Ipv6Network::new(addr, prefix)
|
Ipv6Network::new(addr, prefix)
|
||||||
}
|
}
|
||||||
@ -192,19 +194,13 @@ impl Iterator for Ipv6NetworkIterator {
|
|||||||
type Item = Ipv6Addr;
|
type Item = Ipv6Addr;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Ipv6Addr> {
|
fn next(&mut self) -> Option<Ipv6Addr> {
|
||||||
|
|
||||||
if self.next <= self.end {
|
if self.next <= self.end {
|
||||||
|
|
||||||
let next = Ipv6Addr::from(self.next);
|
let next = Ipv6Addr::from(self.next);
|
||||||
self.next += 1;
|
self.next += 1;
|
||||||
Some(next)
|
Some(next)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
None
|
None
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,10 +334,22 @@ mod test {
|
|||||||
fn iterator_v6() {
|
fn iterator_v6() {
|
||||||
let cidr: Ipv6Network = "2001:db8::/126".parse().unwrap();
|
let cidr: Ipv6Network = "2001:db8::/126".parse().unwrap();
|
||||||
let mut iter = cidr.iter();
|
let mut iter = cidr.iter();
|
||||||
assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0), iter.next().unwrap());
|
assert_eq!(
|
||||||
assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), iter.next().unwrap());
|
Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0),
|
||||||
assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 2), iter.next().unwrap());
|
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, 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());
|
assert_eq!(None, iter.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +358,10 @@ mod test {
|
|||||||
fn iterator_v6_tiny() {
|
fn iterator_v6_tiny() {
|
||||||
let cidr: Ipv6Network = "2001:db8::/128".parse().unwrap();
|
let cidr: Ipv6Network = "2001:db8::/128".parse().unwrap();
|
||||||
let mut iter = cidr.iter();
|
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());
|
assert_eq!(None, iter.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ pub use common::IpNetworkError;
|
|||||||
|
|
||||||
/// 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.
|
||||||
#[derive(Debug,Clone,Copy,Hash,PartialEq,Eq,PartialOrd,Ord)]
|
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum IpNetwork {
|
pub enum IpNetwork {
|
||||||
V4(Ipv4Network),
|
V4(Ipv4Network),
|
||||||
V6(Ipv6Network),
|
V6(Ipv6Network),
|
||||||
|
Reference in New Issue
Block a user