mirror of
https://github.com/achanda/ipnetwork.git
synced 2025-06-16 08:48:51 +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:
|
||||
global:
|
||||
- secure: gokQ7xIWwmAuEUW3IyS5B/pbZxdFSSDBto5beJ+4ACGcRMDqJ/eCPf1ekSVXME4TWM46uUCjxcdUjYhIhQ6sG4zfWck4u45qRJ5JbIoTvR+ykxhN1j3Zi5x9ptP3ALDbHn2i3v6t9xohORfQpz3dVND5c7thbYDyKP2ZR1sez5c=
|
||||
- FEATURES: default
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- rust: nightly
|
||||
env: FEATURES=ipv6-iterator
|
||||
|
||||
script:
|
||||
- cargo build --verbose
|
||||
- cargo test --verbose
|
||||
- cargo build --release --verbose
|
||||
- cargo doc --verbose
|
||||
- cargo build --features $FEATURES --verbose
|
||||
- cargo test --features $FEATURES --verbose
|
||||
- cargo build --features $FEATURES --release --verbose
|
||||
- cargo doc --features $FEATURES --verbose
|
||||
|
||||
after_script:
|
||||
- curl http://www.rust-ci.org/artifacts/put?t=$RUSTCI_TOKEN | sh
|
||||
|
@ -16,3 +16,4 @@ clippy = {version = "0.0.104", optional = true}
|
||||
[features]
|
||||
default = []
|
||||
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 {
|
||||
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 {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "{}/{}", self.ip(), self.prefix())
|
||||
@ -208,4 +258,36 @@ mod test {
|
||||
let prefix = ipv6_mask_to_prefix(mask);
|
||||
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.
|
||||
#![cfg_attr(feature = "dev", feature(plugin))]
|
||||
#![cfg_attr(feature = "dev", plugin(clippy))]
|
||||
#![cfg_attr(feature = "ipv6-iterator", feature(i128_type))]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
use std::fmt;
|
||||
|
Reference in New Issue
Block a user