mirror of
https://github.com/achanda/ipnetwork.git
synced 2025-06-16 16:58:50 +00:00
Merge pull request #6 from faern/nth-size-methods
Add size and nth to Ipv4Network
This commit is contained in:
84
src/lib.rs
84
src/lib.rs
@ -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);
|
||||
|
Reference in New Issue
Block a user