mirror of
https://github.com/achanda/ipnetwork.git
synced 2025-06-18 17:57:10 +00:00
Add an iterator for ipv6 network. (#49)
This is feature gated since i128 is not stable yet
This commit is contained in:

committed by
Abhishek Chanda

parent
fb8f735741
commit
99203160b9
14
.travis.yml
14
.travis.yml
@ -6,12 +6,18 @@ rust:
|
|||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- secure: gokQ7xIWwmAuEUW3IyS5B/pbZxdFSSDBto5beJ+4ACGcRMDqJ/eCPf1ekSVXME4TWM46uUCjxcdUjYhIhQ6sG4zfWck4u45qRJ5JbIoTvR+ykxhN1j3Zi5x9ptP3ALDbHn2i3v6t9xohORfQpz3dVND5c7thbYDyKP2ZR1sez5c=
|
- secure: gokQ7xIWwmAuEUW3IyS5B/pbZxdFSSDBto5beJ+4ACGcRMDqJ/eCPf1ekSVXME4TWM46uUCjxcdUjYhIhQ6sG4zfWck4u45qRJ5JbIoTvR+ykxhN1j3Zi5x9ptP3ALDbHn2i3v6t9xohORfQpz3dVND5c7thbYDyKP2ZR1sez5c=
|
||||||
|
- FEATURES: default
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- rust: nightly
|
||||||
|
env: FEATURES=ipv6-iterator
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- cargo build --verbose
|
- cargo build --features $FEATURES --verbose
|
||||||
- cargo test --verbose
|
- cargo test --features $FEATURES --verbose
|
||||||
- cargo build --release --verbose
|
- cargo build --features $FEATURES --release --verbose
|
||||||
- cargo doc --verbose
|
- cargo doc --features $FEATURES --verbose
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
- curl http://www.rust-ci.org/artifacts/put?t=$RUSTCI_TOKEN | sh
|
- curl http://www.rust-ci.org/artifacts/put?t=$RUSTCI_TOKEN | sh
|
||||||
|
@ -16,3 +16,4 @@ clippy = {version = "0.0.104", optional = true}
|
|||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
dev = ["clippy"]
|
dev = ["clippy"]
|
||||||
|
ipv6-iterator = []
|
||||||
|
82
src/ipv6.rs
82
src/ipv6.rs
@ -29,6 +29,29 @@ impl Ipv6Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over `Ipv6Network`. Each call to `next` will return the next
|
||||||
|
/// `Ipv6Addr` in the given network. `None` will be returned when there are no more
|
||||||
|
/// 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;
|
||||||
|
|
||||||
|
let mask = max.checked_shl((IPV6_BITS - prefix) as u32).unwrap_or(0);
|
||||||
|
let start: u128 = dec & mask;
|
||||||
|
|
||||||
|
let mask = max.checked_shr(prefix as u32).unwrap_or(0);
|
||||||
|
let end: u128 = dec | mask;
|
||||||
|
|
||||||
|
Ipv6NetworkIterator{
|
||||||
|
next: start,
|
||||||
|
end: end,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ip(&self) -> Ipv6Addr {
|
pub fn ip(&self) -> Ipv6Addr {
|
||||||
self.addr
|
self.addr
|
||||||
}
|
}
|
||||||
@ -90,6 +113,33 @@ impl FromStr for Ipv6Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ipv6-iterator")]
|
||||||
|
pub struct Ipv6NetworkIterator {
|
||||||
|
next: u128,
|
||||||
|
end: u128,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ipv6-iterator")]
|
||||||
|
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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Ipv6Network {
|
impl fmt::Display for Ipv6Network {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(fmt, "{}/{}", self.ip(), self.prefix())
|
write!(fmt, "{}/{}", self.ip(), self.prefix())
|
||||||
@ -208,4 +258,36 @@ mod test {
|
|||||||
let prefix = ipv6_mask_to_prefix(mask);
|
let prefix = ipv6_mask_to_prefix(mask);
|
||||||
assert!(prefix.is_err());
|
assert!(prefix.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "ipv6-iterator")]
|
||||||
|
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!(None, iter.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "ipv6-iterator")]
|
||||||
|
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!(None, iter.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "ipv6-iterator")]
|
||||||
|
fn iterator_v6_huge() {
|
||||||
|
let cidr: Ipv6Network = "2001:db8::/0".parse().unwrap();
|
||||||
|
let mut iter = cidr.iter();
|
||||||
|
assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), iter.next().unwrap());
|
||||||
|
assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), iter.next().unwrap());
|
||||||
|
assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 2), iter.next().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
//! is still WIP.
|
//! is still WIP.
|
||||||
#![cfg_attr(feature = "dev", feature(plugin))]
|
#![cfg_attr(feature = "dev", feature(plugin))]
|
||||||
#![cfg_attr(feature = "dev", plugin(clippy))]
|
#![cfg_attr(feature = "dev", plugin(clippy))]
|
||||||
|
#![cfg_attr(feature = "ipv6-iterator", feature(i128_type))]
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
Reference in New Issue
Block a user