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;
|
||||
|
||||
/// 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::<Vec<&str>>();
|
||||
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<u8, IpNetworkError> {
|
||||
let mask = prefix.parse::<u8>().map_err(|_| IpNetworkError::InvalidPrefix)?;
|
||||
let mask = prefix
|
||||
.parse::<u8>()
|
||||
.map_err(|_| IpNetworkError::InvalidPrefix)?;
|
||||
if mask > max {
|
||||
Err(IpNetworkError::InvalidPrefix)
|
||||
} else {
|
||||
@ -58,11 +65,14 @@ pub fn parse_addr(addr: &str) -> Result<Ipv4Addr, IpNetworkError> {
|
||||
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]))
|
||||
}
|
||||
|
@ -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<Ipv4Addr> for Ipv4Network {
|
||||
fn from(a: Ipv4Addr) -> Ipv4Network {
|
||||
Ipv4Network {
|
||||
|
49
src/ipv6.rs
49
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<Ipv6Network, IpNetworkError> {
|
||||
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<Ipv6Addr> {
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
Reference in New Issue
Block a user