Merge pull request #6 from faern/nth-size-methods

Add size and nth to Ipv4Network
This commit is contained in:
Abhishek Chanda
2016-06-17 22:52:17 -07:00
committed by GitHub

View File

@ -82,6 +82,51 @@ impl Ipv4Network {
(u32::from(ip) & mask) == net
}
/// Returns number of possible host addresses in this `Ipv4Network`.
///
/// # Examples
///
/// ```
/// use std::net::Ipv4Addr;
/// use ipnetwork::Ipv4Network;
///
/// let net = Ipv4Network::from_cidr("10.1.0.0/16").unwrap();
/// assert_eq!(net.size(), 65536);
///
/// let tinynet = Ipv4Network::from_cidr("0.0.0.0/32").unwrap();
/// assert_eq!(tinynet.size(), 1);
/// ```
pub fn size(&self) -> u64 {
let host_bits = (IPV4_BITS - self.prefix) as u32;
(2 as u64).pow(host_bits)
}
/// Returns the `n`:th address within this network.
/// The adresses are indexed from 0 and `n` must be smaller than the size of the network.
///
/// # Examples
///
/// ```
/// use std::net::Ipv4Addr;
/// use ipnetwork::Ipv4Network;
///
/// let net = Ipv4Network::from_cidr("192.168.0.0/24").unwrap();
/// assert_eq!(net.nth(0).unwrap(), Ipv4Addr::new(192, 168, 0, 0));
/// assert_eq!(net.nth(15).unwrap(), Ipv4Addr::new(192, 168, 0, 15));
/// assert!(net.nth(256).is_none());
///
/// let net2 = Ipv4Network::from_cidr("10.0.0.0/16").unwrap();
/// assert_eq!(net2.nth(256).unwrap(), Ipv4Addr::new(10, 0, 1, 0));
/// ```
pub fn nth(&self, n: u32) -> Option<Ipv4Addr> {
if (n as u64) < self.size() {
let (_, net) = self.network();
Some(Ipv4Addr::from(net + n))
} else {
None
}
}
fn parse_addr(addr: &str) -> Result<Ipv4Addr, String> {
let byte_strs = addr.split('.')
.map(|b| b.parse::<u8>())
@ -235,6 +280,45 @@ mod test {
assert!(cidr.is_err());
}
#[test]
fn size_v4_24bit() {
let net = Ipv4Network::from_cidr("0/24").unwrap();
assert_eq!(net.size(), 256);
}
#[test]
fn size_v4_1bit() {
let net = Ipv4Network::from_cidr("0/31").unwrap();
assert_eq!(net.size(), 2);
}
#[test]
fn size_v4_max() {
let net = Ipv4Network::from_cidr("0/0").unwrap();
assert_eq!(net.size(), 4_294_967_296);
}
#[test]
fn size_v4_min() {
let net = Ipv4Network::from_cidr("0/32").unwrap();
assert_eq!(net.size(), 1);
}
#[test]
fn nth_v4() {
let cidr = Ipv4Network::new(Ipv4Addr::new(127, 0, 0, 0), 24);
assert_eq!(cidr.nth(0).unwrap(), Ipv4Addr::new(127, 0, 0, 0));
assert_eq!(cidr.nth(1).unwrap(), Ipv4Addr::new(127, 0, 0, 1));
assert_eq!(cidr.nth(255).unwrap(), Ipv4Addr::new(127, 0, 0, 255));
assert!(cidr.nth(256).is_none());
}
#[test]
fn nth_v4_fail() {
let cidr = Ipv4Network::new(Ipv4Addr::new(10, 0, 0, 0), 32);
assert!(cidr.nth(1).is_none());
}
#[test]
fn create_v6() {
let cidr = Ipv6Network::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), 24);