1 //! Extensions to the standard IP address types for common operations. 2 //! 3 //! The [`IpAdd`], [`IpSub`], [`IpBitAnd`], [`IpBitOr`] traits extend 4 //! the `Ipv4Addr` and `Ipv6Addr` types with methods to perform these 5 //! operations. 6 7 use std::cmp::Ordering::{Less, Equal}; 8 use std::iter::{FusedIterator, DoubleEndedIterator}; 9 use std::mem; 10 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; 11 12 /// Provides a `saturating_add()` method for `Ipv4Addr` and `Ipv6Addr`. 13 /// 14 /// Adding an integer to an IP address returns the modified IP address. 15 /// A `u32` may added to an IPv4 address and a `u128` may be added to 16 /// an IPv6 address. 17 /// 18 /// # Examples 19 /// 20 /// ``` 21 /// use std::net::{Ipv4Addr, Ipv6Addr}; 22 /// use ipnet::IpAdd; 23 /// 24 /// let ip0: Ipv4Addr = "192.168.0.0".parse().unwrap(); 25 /// let ip1: Ipv4Addr = "192.168.0.5".parse().unwrap(); 26 /// let ip2: Ipv4Addr = "255.255.255.254".parse().unwrap(); 27 /// let max: Ipv4Addr = "255.255.255.255".parse().unwrap(); 28 /// 29 /// assert_eq!(ip0.saturating_add(5), ip1); 30 /// assert_eq!(ip2.saturating_add(1), max); 31 /// assert_eq!(ip2.saturating_add(5), max); 32 /// 33 /// let ip0: Ipv6Addr = "fd00::".parse().unwrap(); 34 /// let ip1: Ipv6Addr = "fd00::5".parse().unwrap(); 35 /// let ip2: Ipv6Addr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe".parse().unwrap(); 36 /// let max: Ipv6Addr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(); 37 /// 38 /// assert_eq!(ip0.saturating_add(5), ip1); 39 /// assert_eq!(ip2.saturating_add(1), max); 40 /// assert_eq!(ip2.saturating_add(5), max); 41 /// ``` 42 pub trait IpAdd<RHS = Self> { 43 type Output; saturating_add(self, rhs: RHS) -> Self::Output44 fn saturating_add(self, rhs: RHS) -> Self::Output; 45 } 46 47 /// Provides a `saturating_sub()` method for `Ipv4Addr` and `Ipv6Addr`. 48 /// 49 /// Subtracting an integer from an IP address returns the modified IP 50 /// address. A `u32` may be subtracted from an IPv4 address and a `u128` 51 /// may be subtracted from an IPv6 address. 52 /// 53 /// Subtracting an IP address from another IP address of the same type 54 /// returns an integer of the appropriate width. A `u32` for IPv4 and a 55 /// `u128` for IPv6. Subtracting IP addresses is useful for getting 56 /// the range between two IP addresses. 57 /// 58 /// # Examples 59 /// 60 /// ``` 61 /// use std::net::{Ipv4Addr, Ipv6Addr}; 62 /// use ipnet::IpSub; 63 /// 64 /// let min: Ipv4Addr = "0.0.0.0".parse().unwrap(); 65 /// let ip1: Ipv4Addr = "192.168.1.5".parse().unwrap(); 66 /// let ip2: Ipv4Addr = "192.168.1.100".parse().unwrap(); 67 /// 68 /// assert_eq!(min.saturating_sub(ip1), 0); 69 /// assert_eq!(ip2.saturating_sub(ip1), 95); 70 /// assert_eq!(min.saturating_sub(5), min); 71 /// assert_eq!(ip2.saturating_sub(95), ip1); 72 /// 73 /// let min: Ipv6Addr = "::".parse().unwrap(); 74 /// let ip1: Ipv6Addr = "fd00::5".parse().unwrap(); 75 /// let ip2: Ipv6Addr = "fd00::64".parse().unwrap(); 76 /// 77 /// assert_eq!(min.saturating_sub(ip1), 0); 78 /// assert_eq!(ip2.saturating_sub(ip1), 95); 79 /// assert_eq!(min.saturating_sub(5u128), min); 80 /// assert_eq!(ip2.saturating_sub(95u128), ip1); 81 /// ``` 82 pub trait IpSub<RHS = Self> { 83 type Output; saturating_sub(self, rhs: RHS) -> Self::Output84 fn saturating_sub(self, rhs: RHS) -> Self::Output; 85 } 86 87 /// Provides a `bitand()` method for `Ipv4Addr` and `Ipv6Addr`. 88 /// 89 /// # Examples 90 /// 91 /// ``` 92 /// use std::net::{Ipv4Addr, Ipv6Addr}; 93 /// use ipnet::IpBitAnd; 94 /// 95 /// let ip: Ipv4Addr = "192.168.1.1".parse().unwrap(); 96 /// let mask: Ipv4Addr = "255.255.0.0".parse().unwrap(); 97 /// let res: Ipv4Addr = "192.168.0.0".parse().unwrap(); 98 /// 99 /// assert_eq!(ip.bitand(mask), res); 100 /// assert_eq!(ip.bitand(0xffff0000), res); 101 /// 102 /// let ip: Ipv6Addr = "fd00:1234::1".parse().unwrap(); 103 /// let mask: Ipv6Addr = "ffff::".parse().unwrap(); 104 /// let res: Ipv6Addr = "fd00::".parse().unwrap(); 105 /// 106 /// assert_eq!(ip.bitand(mask), res); 107 /// assert_eq!(ip.bitand(0xffff_0000_0000_0000_0000_0000_0000_0000u128), res); 108 /// ``` 109 pub trait IpBitAnd<RHS = Self> { 110 type Output; bitand(self, rhs: RHS) -> Self::Output111 fn bitand(self, rhs: RHS) -> Self::Output; 112 } 113 114 /// Provides a `bitor()` method for `Ipv4Addr` and `Ipv6Addr`. 115 /// 116 /// # Examples 117 /// 118 /// ``` 119 /// use std::net::{Ipv4Addr, Ipv6Addr}; 120 /// use ipnet::IpBitOr; 121 /// 122 /// let ip: Ipv4Addr = "10.1.1.1".parse().unwrap(); 123 /// let mask: Ipv4Addr = "0.0.0.255".parse().unwrap(); 124 /// let res: Ipv4Addr = "10.1.1.255".parse().unwrap(); 125 /// 126 /// assert_eq!(ip.bitor(mask), res); 127 /// assert_eq!(ip.bitor(0x000000ff), res); 128 /// 129 /// let ip: Ipv6Addr = "fd00::1".parse().unwrap(); 130 /// let mask: Ipv6Addr = "::ffff:ffff".parse().unwrap(); 131 /// let res: Ipv6Addr = "fd00::ffff:ffff".parse().unwrap(); 132 /// 133 /// assert_eq!(ip.bitor(mask), res); 134 /// assert_eq!(ip.bitor(u128::from(0xffffffffu32)), res); 135 /// ``` 136 pub trait IpBitOr<RHS = Self> { 137 type Output; bitor(self, rhs: RHS) -> Self::Output138 fn bitor(self, rhs: RHS) -> Self::Output; 139 } 140 141 macro_rules! ip_add_impl { 142 ($lhs:ty, $rhs:ty, $output:ty, $inner:ty) => ( 143 impl IpAdd<$rhs> for $lhs { 144 type Output = $output; 145 146 fn saturating_add(self, rhs: $rhs) -> $output { 147 let lhs: $inner = self.into(); 148 let rhs: $inner = rhs.into(); 149 (lhs.saturating_add(rhs.into())).into() 150 } 151 } 152 ) 153 } 154 155 macro_rules! ip_sub_impl { 156 ($lhs:ty, $rhs:ty, $output:ty, $inner:ty) => ( 157 impl IpSub<$rhs> for $lhs { 158 type Output = $output; 159 160 fn saturating_sub(self, rhs: $rhs) -> $output { 161 let lhs: $inner = self.into(); 162 let rhs: $inner = rhs.into(); 163 (lhs.saturating_sub(rhs.into())).into() 164 } 165 } 166 ) 167 } 168 169 ip_add_impl!(Ipv4Addr, u32, Ipv4Addr, u32); 170 ip_add_impl!(Ipv6Addr, u128, Ipv6Addr, u128); 171 172 ip_sub_impl!(Ipv4Addr, Ipv4Addr, u32, u32); 173 ip_sub_impl!(Ipv4Addr, u32, Ipv4Addr, u32); 174 ip_sub_impl!(Ipv6Addr, Ipv6Addr, u128, u128); 175 ip_sub_impl!(Ipv6Addr, u128, Ipv6Addr, u128); 176 177 macro_rules! ip_bitops_impl { 178 ($(($lhs:ty, $rhs:ty, $t:ty),)*) => { 179 $( 180 impl IpBitAnd<$rhs> for $lhs { 181 type Output = $lhs; 182 183 fn bitand(self, rhs: $rhs) -> $lhs { 184 let lhs: $t = self.into(); 185 let rhs: $t = rhs.into(); 186 (lhs & rhs).into() 187 } 188 } 189 190 impl IpBitOr<$rhs> for $lhs { 191 type Output = $lhs; 192 193 fn bitor(self, rhs: $rhs) -> $lhs { 194 let lhs: $t = self.into(); 195 let rhs: $t = rhs.into(); 196 (lhs | rhs).into() 197 } 198 } 199 )* 200 } 201 } 202 203 ip_bitops_impl! { 204 (Ipv4Addr, Ipv4Addr, u32), 205 (Ipv4Addr, u32, u32), 206 (Ipv6Addr, Ipv6Addr, u128), 207 (Ipv6Addr, u128, u128), 208 } 209 210 // A barebones copy of the current unstable Step trait used by the 211 // IpAddrRange, Ipv4AddrRange, and Ipv6AddrRange types below, and the 212 // Subnets types in ipnet. 213 pub trait IpStep { replace_one(&mut self) -> Self214 fn replace_one(&mut self) -> Self; replace_zero(&mut self) -> Self215 fn replace_zero(&mut self) -> Self; add_one(&self) -> Self216 fn add_one(&self) -> Self; sub_one(&self) -> Self217 fn sub_one(&self) -> Self; 218 } 219 220 impl IpStep for Ipv4Addr { replace_one(&mut self) -> Self221 fn replace_one(&mut self) -> Self { 222 mem::replace(self, Ipv4Addr::new(0, 0, 0, 1)) 223 } replace_zero(&mut self) -> Self224 fn replace_zero(&mut self) -> Self { 225 mem::replace(self, Ipv4Addr::new(0, 0, 0, 0)) 226 } add_one(&self) -> Self227 fn add_one(&self) -> Self { 228 self.saturating_add(1) 229 } sub_one(&self) -> Self230 fn sub_one(&self) -> Self { 231 self.saturating_sub(1) 232 } 233 } 234 235 impl IpStep for Ipv6Addr { replace_one(&mut self) -> Self236 fn replace_one(&mut self) -> Self { 237 mem::replace(self, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)) 238 } replace_zero(&mut self) -> Self239 fn replace_zero(&mut self) -> Self { 240 mem::replace(self, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)) 241 } add_one(&self) -> Self242 fn add_one(&self) -> Self { 243 self.saturating_add(1) 244 } sub_one(&self) -> Self245 fn sub_one(&self) -> Self { 246 self.saturating_sub(1) 247 } 248 } 249 250 /// An `Iterator` over a range of IP addresses, either IPv4 or IPv6. 251 /// 252 /// # Examples 253 /// 254 /// ``` 255 /// use std::net::IpAddr; 256 /// use ipnet::{IpAddrRange, Ipv4AddrRange, Ipv6AddrRange}; 257 /// 258 /// let hosts = IpAddrRange::from(Ipv4AddrRange::new( 259 /// "10.0.0.0".parse().unwrap(), 260 /// "10.0.0.3".parse().unwrap(), 261 /// )); 262 /// 263 /// assert_eq!(hosts.collect::<Vec<IpAddr>>(), vec![ 264 /// "10.0.0.0".parse::<IpAddr>().unwrap(), 265 /// "10.0.0.1".parse().unwrap(), 266 /// "10.0.0.2".parse().unwrap(), 267 /// "10.0.0.3".parse().unwrap(), 268 /// ]); 269 /// 270 /// let hosts = IpAddrRange::from(Ipv6AddrRange::new( 271 /// "fd00::".parse().unwrap(), 272 /// "fd00::3".parse().unwrap(), 273 /// )); 274 /// 275 /// assert_eq!(hosts.collect::<Vec<IpAddr>>(), vec![ 276 /// "fd00::0".parse::<IpAddr>().unwrap(), 277 /// "fd00::1".parse().unwrap(), 278 /// "fd00::2".parse().unwrap(), 279 /// "fd00::3".parse().unwrap(), 280 /// ]); 281 /// ``` 282 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] 283 pub enum IpAddrRange { 284 V4(Ipv4AddrRange), 285 V6(Ipv6AddrRange), 286 } 287 288 /// An `Iterator` over a range of IPv4 addresses. 289 /// 290 /// # Examples 291 /// 292 /// ``` 293 /// use std::net::Ipv4Addr; 294 /// use ipnet::Ipv4AddrRange; 295 /// 296 /// let hosts = Ipv4AddrRange::new( 297 /// "10.0.0.0".parse().unwrap(), 298 /// "10.0.0.3".parse().unwrap(), 299 /// ); 300 /// 301 /// assert_eq!(hosts.collect::<Vec<Ipv4Addr>>(), vec![ 302 /// "10.0.0.0".parse::<Ipv4Addr>().unwrap(), 303 /// "10.0.0.1".parse().unwrap(), 304 /// "10.0.0.2".parse().unwrap(), 305 /// "10.0.0.3".parse().unwrap(), 306 /// ]); 307 /// ``` 308 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] 309 pub struct Ipv4AddrRange { 310 start: Ipv4Addr, 311 end: Ipv4Addr, 312 } 313 314 /// An `Iterator` over a range of IPv6 addresses. 315 /// 316 /// # Examples 317 /// 318 /// ``` 319 /// use std::net::Ipv6Addr; 320 /// use ipnet::Ipv6AddrRange; 321 /// 322 /// let hosts = Ipv6AddrRange::new( 323 /// "fd00::".parse().unwrap(), 324 /// "fd00::3".parse().unwrap(), 325 /// ); 326 /// 327 /// assert_eq!(hosts.collect::<Vec<Ipv6Addr>>(), vec![ 328 /// "fd00::".parse::<Ipv6Addr>().unwrap(), 329 /// "fd00::1".parse().unwrap(), 330 /// "fd00::2".parse().unwrap(), 331 /// "fd00::3".parse().unwrap(), 332 /// ]); 333 /// ``` 334 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] 335 pub struct Ipv6AddrRange { 336 start: Ipv6Addr, 337 end: Ipv6Addr, 338 } 339 340 impl From<Ipv4AddrRange> for IpAddrRange { from(i: Ipv4AddrRange) -> IpAddrRange341 fn from(i: Ipv4AddrRange) -> IpAddrRange { 342 IpAddrRange::V4(i) 343 } 344 } 345 346 impl From<Ipv6AddrRange> for IpAddrRange { from(i: Ipv6AddrRange) -> IpAddrRange347 fn from(i: Ipv6AddrRange) -> IpAddrRange { 348 IpAddrRange::V6(i) 349 } 350 } 351 352 impl Ipv4AddrRange { new(start: Ipv4Addr, end: Ipv4Addr) -> Self353 pub fn new(start: Ipv4Addr, end: Ipv4Addr) -> Self { 354 Ipv4AddrRange { 355 start: start, 356 end: end, 357 } 358 } 359 /// Counts the number of Ipv4Addr in this range. 360 /// This method will never overflow or panic. count_u64(&self) -> u64361 fn count_u64(&self) -> u64 { 362 match self.start.partial_cmp(&self.end) { 363 Some(Less) => { 364 let count: u32 = self.end.saturating_sub(self.start); 365 let count = count as u64 + 1; // Never overflows 366 count 367 }, 368 Some(Equal) => 1, 369 _ => 0, 370 } 371 } 372 } 373 374 impl Ipv6AddrRange { new(start: Ipv6Addr, end: Ipv6Addr) -> Self375 pub fn new(start: Ipv6Addr, end: Ipv6Addr) -> Self { 376 Ipv6AddrRange { 377 start: start, 378 end: end, 379 } 380 } 381 /// Counts the number of Ipv6Addr in this range. 382 /// This method may overflow or panic if start 383 /// is 0 and end is u128::MAX count_u128(&self) -> u128384 fn count_u128(&self) -> u128 { 385 match self.start.partial_cmp(&self.end) { 386 Some(Less) => { 387 let count = self.end.saturating_sub(self.start); 388 // May overflow or panic 389 count + 1 390 }, 391 Some(Equal) => 1, 392 _ => 0, 393 } 394 } 395 /// True only if count_u128 does not overflow can_count_u128(&self) -> bool396 fn can_count_u128(&self) -> bool { 397 self.start != Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0) 398 || self.end != Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff) 399 } 400 } 401 402 impl Iterator for IpAddrRange { 403 type Item = IpAddr; 404 next(&mut self) -> Option<Self::Item>405 fn next(&mut self) -> Option<Self::Item> { 406 match *self { 407 IpAddrRange::V4(ref mut a) => a.next().map(IpAddr::V4), 408 IpAddrRange::V6(ref mut a) => a.next().map(IpAddr::V6), 409 } 410 } 411 count(self) -> usize412 fn count(self) -> usize { 413 match self { 414 IpAddrRange::V4(a) => a.count(), 415 IpAddrRange::V6(a) => a.count(), 416 } 417 } 418 last(self) -> Option<Self::Item>419 fn last(self) -> Option<Self::Item> { 420 match self { 421 IpAddrRange::V4(a) => a.last().map(IpAddr::V4), 422 IpAddrRange::V6(a) => a.last().map(IpAddr::V6), 423 } 424 } 425 max(self) -> Option<Self::Item>426 fn max(self) -> Option<Self::Item> { 427 match self { 428 IpAddrRange::V4(a) => Iterator::max(a).map(IpAddr::V4), 429 IpAddrRange::V6(a) => Iterator::max(a).map(IpAddr::V6), 430 } 431 } 432 min(self) -> Option<Self::Item>433 fn min(self) -> Option<Self::Item> { 434 match self { 435 IpAddrRange::V4(a) => Iterator::min(a).map(IpAddr::V4), 436 IpAddrRange::V6(a) => Iterator::min(a).map(IpAddr::V6), 437 } 438 } 439 nth(&mut self, n: usize) -> Option<Self::Item>440 fn nth(&mut self, n: usize) -> Option<Self::Item> { 441 match *self { 442 IpAddrRange::V4(ref mut a) => a.nth(n).map(IpAddr::V4), 443 IpAddrRange::V6(ref mut a) => a.nth(n).map(IpAddr::V6), 444 } 445 } 446 size_hint(&self) -> (usize, Option<usize>)447 fn size_hint(&self) -> (usize, Option<usize>) { 448 match *self { 449 IpAddrRange::V4(ref a) => a.size_hint(), 450 IpAddrRange::V6(ref a) => a.size_hint(), 451 } 452 } 453 } 454 455 impl Iterator for Ipv4AddrRange { 456 type Item = Ipv4Addr; 457 next(&mut self) -> Option<Self::Item>458 fn next(&mut self) -> Option<Self::Item> { 459 match self.start.partial_cmp(&self.end) { 460 Some(Less) => { 461 let next = self.start.add_one(); 462 Some(mem::replace(&mut self.start, next)) 463 }, 464 Some(Equal) => { 465 self.end.replace_zero(); 466 Some(self.start.replace_one()) 467 }, 468 _ => None, 469 } 470 } 471 472 #[allow(const_err)] 473 #[allow(arithmetic_overflow)] count(self) -> usize474 fn count(self) -> usize { 475 match self.start.partial_cmp(&self.end) { 476 Some(Less) => { 477 // Adding one here might overflow u32. 478 // Instead, wait until after converted to usize 479 let count: u32 = self.end.saturating_sub(self.start); 480 481 // usize might only be 16 bits, 482 // so need to explicitely check for overflow. 483 // 'usize::MAX as u32' is okay here - if usize is 64 bits, 484 // value truncates to u32::MAX 485 if count <= std::usize::MAX as u32 { 486 count as usize + 1 487 // count overflows usize 488 } else { 489 // emulate standard overflow/panic behavior 490 std::usize::MAX + 2 + count as usize 491 } 492 }, 493 Some(Equal) => 1, 494 _ => 0 495 } 496 } 497 last(self) -> Option<Self::Item>498 fn last(self) -> Option<Self::Item> { 499 match self.start.partial_cmp(&self.end) { 500 Some(Less) | Some(Equal) => Some(self.end), 501 _ => None, 502 } 503 } 504 max(self) -> Option<Self::Item>505 fn max(self) -> Option<Self::Item> { 506 self.last() 507 } 508 min(self) -> Option<Self::Item>509 fn min(self) -> Option<Self::Item> { 510 match self.start.partial_cmp(&self.end) { 511 Some(Less) | Some(Equal) => Some(self.start), 512 _ => None 513 } 514 } 515 nth(&mut self, n: usize) -> Option<Self::Item>516 fn nth(&mut self, n: usize) -> Option<Self::Item> { 517 let n = n as u64; 518 let count = self.count_u64(); 519 if n >= count { 520 self.end.replace_zero(); 521 self.start.replace_one(); 522 None 523 } else if n == count - 1 { 524 self.start.replace_one(); 525 Some(self.end.replace_zero()) 526 } else { 527 let nth = self.start.saturating_add(n as u32); 528 self.start = nth.add_one(); 529 Some(nth) 530 } 531 } 532 size_hint(&self) -> (usize, Option<usize>)533 fn size_hint(&self) -> (usize, Option<usize>) { 534 let count = self.count_u64(); 535 if count > std::usize::MAX as u64 { 536 (std::usize::MAX, None) 537 } else { 538 let count = count as usize; 539 (count, Some(count)) 540 } 541 } 542 } 543 544 impl Iterator for Ipv6AddrRange { 545 type Item = Ipv6Addr; 546 next(&mut self) -> Option<Self::Item>547 fn next(&mut self) -> Option<Self::Item> { 548 match self.start.partial_cmp(&self.end) { 549 Some(Less) => { 550 let next = self.start.add_one(); 551 Some(mem::replace(&mut self.start, next)) 552 }, 553 Some(Equal) => { 554 self.end.replace_zero(); 555 Some(self.start.replace_one()) 556 }, 557 _ => None, 558 } 559 } 560 561 #[allow(const_err)] 562 #[allow(arithmetic_overflow)] count(self) -> usize563 fn count(self) -> usize { 564 let count = self.count_u128(); 565 // count fits in usize 566 if count <= std::usize::MAX as u128 { 567 count as usize 568 // count does not fit in usize 569 } else { 570 // emulate standard overflow/panic behavior 571 std::usize::MAX + 1 + count as usize 572 } 573 } 574 last(self) -> Option<Self::Item>575 fn last(self) -> Option<Self::Item> { 576 match self.start.partial_cmp(&self.end) { 577 Some(Less) | Some(Equal) => Some(self.end), 578 _ => None, 579 } 580 } 581 max(self) -> Option<Self::Item>582 fn max(self) -> Option<Self::Item> { 583 self.last() 584 } 585 min(self) -> Option<Self::Item>586 fn min(self) -> Option<Self::Item> { 587 match self.start.partial_cmp(&self.end) { 588 Some(Less) | Some(Equal) => Some(self.start), 589 _ => None 590 } 591 } 592 nth(&mut self, n: usize) -> Option<Self::Item>593 fn nth(&mut self, n: usize) -> Option<Self::Item> { 594 let n = n as u128; 595 if self.can_count_u128() { 596 let count = self.count_u128(); 597 if n >= count { 598 self.end.replace_zero(); 599 self.start.replace_one(); 600 None 601 } else if n == count - 1 { 602 self.start.replace_one(); 603 Some(self.end.replace_zero()) 604 } else { 605 let nth = self.start.saturating_add(n); 606 self.start = nth.add_one(); 607 Some(nth) 608 } 609 // count overflows u128; n is 64-bits at most. 610 // therefore, n can never exceed count 611 } else { 612 let nth = self.start.saturating_add(n); 613 self.start = nth.add_one(); 614 Some(nth) 615 } 616 } 617 size_hint(&self) -> (usize, Option<usize>)618 fn size_hint(&self) -> (usize, Option<usize>) { 619 if self.can_count_u128() { 620 let count = self.count_u128(); 621 if count > std::usize::MAX as u128 { 622 (std::usize::MAX, None) 623 } else { 624 let count = count as usize; 625 (count, Some(count)) 626 } 627 } else { 628 (std::usize::MAX, None) 629 } 630 } 631 } 632 633 impl DoubleEndedIterator for IpAddrRange { next_back(&mut self) -> Option<Self::Item>634 fn next_back(&mut self) -> Option<Self::Item> { 635 match *self { 636 IpAddrRange::V4(ref mut a) => a.next_back().map(IpAddr::V4), 637 IpAddrRange::V6(ref mut a) => a.next_back().map(IpAddr::V6), 638 } 639 } nth_back(&mut self, n: usize) -> Option<Self::Item>640 fn nth_back(&mut self, n: usize) -> Option<Self::Item> { 641 match *self { 642 IpAddrRange::V4(ref mut a) => a.nth_back(n).map(IpAddr::V4), 643 IpAddrRange::V6(ref mut a) => a.nth_back(n).map(IpAddr::V6), 644 } 645 } 646 } 647 648 impl DoubleEndedIterator for Ipv4AddrRange { next_back(&mut self) -> Option<Self::Item>649 fn next_back(&mut self) -> Option<Self::Item> { 650 match self.start.partial_cmp(&self.end) { 651 Some(Less) => { 652 let next_back = self.end.sub_one(); 653 Some(mem::replace(&mut self.end, next_back)) 654 }, 655 Some(Equal) => { 656 self.end.replace_zero(); 657 Some(self.start.replace_one()) 658 }, 659 _ => None 660 } 661 } nth_back(&mut self, n: usize) -> Option<Self::Item>662 fn nth_back(&mut self, n: usize) -> Option<Self::Item> { 663 let n = n as u64; 664 let count = self.count_u64(); 665 if n >= count { 666 self.end.replace_zero(); 667 self.start.replace_one(); 668 None 669 } else if n == count - 1 { 670 self.end.replace_zero(); 671 Some(self.start.replace_one()) 672 } else { 673 let nth_back = self.end.saturating_sub(n as u32); 674 self.end = nth_back.sub_one(); 675 Some(nth_back) 676 } 677 } 678 } 679 680 impl DoubleEndedIterator for Ipv6AddrRange { next_back(&mut self) -> Option<Self::Item>681 fn next_back(&mut self) -> Option<Self::Item> { 682 match self.start.partial_cmp(&self.end) { 683 Some(Less) => { 684 let next_back = self.end.sub_one(); 685 Some(mem::replace(&mut self.end, next_back)) 686 }, 687 Some(Equal) => { 688 self.end.replace_zero(); 689 Some(self.start.replace_one()) 690 }, 691 _ => None 692 } 693 } nth_back(&mut self, n: usize) -> Option<Self::Item>694 fn nth_back(&mut self, n: usize) -> Option<Self::Item> { 695 let n = n as u128; 696 if self.can_count_u128() { 697 let count = self.count_u128(); 698 if n >= count { 699 self.end.replace_zero(); 700 self.start.replace_one(); 701 None 702 } 703 else if n == count - 1 { 704 self.end.replace_zero(); 705 Some(self.start.replace_one()) 706 } else { 707 let nth_back = self.end.saturating_sub(n); 708 self.end = nth_back.sub_one(); 709 Some(nth_back) 710 } 711 // count overflows u128; n is 64-bits at most. 712 // therefore, n can never exceed count 713 } else { 714 let nth_back = self.end.saturating_sub(n); 715 self.end = nth_back.sub_one(); 716 Some(nth_back) 717 } 718 } 719 } 720 721 impl FusedIterator for IpAddrRange {} 722 impl FusedIterator for Ipv4AddrRange {} 723 impl FusedIterator for Ipv6AddrRange {} 724 725 #[cfg(test)] 726 mod tests { 727 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; 728 use std::str::FromStr; 729 use super::*; 730 731 #[test] test_ipaddrrange()732 fn test_ipaddrrange() { 733 // Next, Next-Back 734 let i = Ipv4AddrRange::new( 735 Ipv4Addr::from_str("10.0.0.0").unwrap(), 736 Ipv4Addr::from_str("10.0.0.3").unwrap() 737 ); 738 739 assert_eq!(i.collect::<Vec<Ipv4Addr>>(), vec![ 740 Ipv4Addr::from_str("10.0.0.0").unwrap(), 741 Ipv4Addr::from_str("10.0.0.1").unwrap(), 742 Ipv4Addr::from_str("10.0.0.2").unwrap(), 743 Ipv4Addr::from_str("10.0.0.3").unwrap(), 744 ]); 745 746 let mut v = i.collect::<Vec<_>>(); 747 v.reverse(); 748 assert_eq!(v, i.rev().collect::<Vec<_>>()); 749 750 let i = Ipv4AddrRange::new( 751 Ipv4Addr::from_str("255.255.255.254").unwrap(), 752 Ipv4Addr::from_str("255.255.255.255").unwrap() 753 ); 754 755 assert_eq!(i.collect::<Vec<Ipv4Addr>>(), vec![ 756 Ipv4Addr::from_str("255.255.255.254").unwrap(), 757 Ipv4Addr::from_str("255.255.255.255").unwrap(), 758 ]); 759 760 let i = Ipv6AddrRange::new( 761 Ipv6Addr::from_str("fd00::").unwrap(), 762 Ipv6Addr::from_str("fd00::3").unwrap(), 763 ); 764 765 assert_eq!(i.collect::<Vec<Ipv6Addr>>(), vec![ 766 Ipv6Addr::from_str("fd00::").unwrap(), 767 Ipv6Addr::from_str("fd00::1").unwrap(), 768 Ipv6Addr::from_str("fd00::2").unwrap(), 769 Ipv6Addr::from_str("fd00::3").unwrap(), 770 ]); 771 772 let mut v = i.collect::<Vec<_>>(); 773 v.reverse(); 774 assert_eq!(v, i.rev().collect::<Vec<_>>()); 775 776 let i = Ipv6AddrRange::new( 777 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(), 778 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), 779 ); 780 781 assert_eq!(i.collect::<Vec<Ipv6Addr>>(), vec![ 782 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(), 783 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), 784 ]); 785 786 let i = IpAddrRange::from(Ipv4AddrRange::new( 787 Ipv4Addr::from_str("10.0.0.0").unwrap(), 788 Ipv4Addr::from_str("10.0.0.3").unwrap(), 789 )); 790 791 assert_eq!(i.collect::<Vec<IpAddr>>(), vec![ 792 IpAddr::from_str("10.0.0.0").unwrap(), 793 IpAddr::from_str("10.0.0.1").unwrap(), 794 IpAddr::from_str("10.0.0.2").unwrap(), 795 IpAddr::from_str("10.0.0.3").unwrap(), 796 ]); 797 798 let mut v = i.collect::<Vec<_>>(); 799 v.reverse(); 800 assert_eq!(v, i.rev().collect::<Vec<_>>()); 801 802 let i = IpAddrRange::from(Ipv4AddrRange::new( 803 Ipv4Addr::from_str("255.255.255.254").unwrap(), 804 Ipv4Addr::from_str("255.255.255.255").unwrap() 805 )); 806 807 assert_eq!(i.collect::<Vec<IpAddr>>(), vec![ 808 IpAddr::from_str("255.255.255.254").unwrap(), 809 IpAddr::from_str("255.255.255.255").unwrap(), 810 ]); 811 812 let i = IpAddrRange::from(Ipv6AddrRange::new( 813 Ipv6Addr::from_str("fd00::").unwrap(), 814 Ipv6Addr::from_str("fd00::3").unwrap(), 815 )); 816 817 assert_eq!(i.collect::<Vec<IpAddr>>(), vec![ 818 IpAddr::from_str("fd00::").unwrap(), 819 IpAddr::from_str("fd00::1").unwrap(), 820 IpAddr::from_str("fd00::2").unwrap(), 821 IpAddr::from_str("fd00::3").unwrap(), 822 ]); 823 824 let mut v = i.collect::<Vec<_>>(); 825 v.reverse(); 826 assert_eq!(v, i.rev().collect::<Vec<_>>()); 827 828 let i = IpAddrRange::from(Ipv6AddrRange::new( 829 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(), 830 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), 831 )); 832 833 assert_eq!(i.collect::<Vec<IpAddr>>(), vec![ 834 IpAddr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(), 835 IpAddr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(), 836 ]); 837 838 // #11 (infinite iterator when start and stop are 0) 839 let zero4 = Ipv4Addr::from_str("0.0.0.0").unwrap(); 840 let zero6 = Ipv6Addr::from_str("::").unwrap(); 841 842 let mut i = Ipv4AddrRange::new(zero4, zero4); 843 assert_eq!(Some(zero4), i.next()); 844 assert_eq!(None, i.next()); 845 846 let mut i = Ipv6AddrRange::new(zero6, zero6); 847 assert_eq!(Some(zero6), i.next()); 848 assert_eq!(None, i.next()); 849 850 // Count 851 let i = Ipv4AddrRange::new( 852 Ipv4Addr::from_str("10.0.0.0").unwrap(), 853 Ipv4Addr::from_str("10.0.0.3").unwrap() 854 ); 855 assert_eq!(i.count(), 4); 856 857 let i = Ipv6AddrRange::new( 858 Ipv6Addr::from_str("fd00::").unwrap(), 859 Ipv6Addr::from_str("fd00::3").unwrap(), 860 ); 861 assert_eq!(i.count(), 4); 862 863 // Size Hint 864 let i = Ipv4AddrRange::new( 865 Ipv4Addr::from_str("10.0.0.0").unwrap(), 866 Ipv4Addr::from_str("10.0.0.3").unwrap() 867 ); 868 assert_eq!(i.size_hint(), (4, Some(4))); 869 870 let i = Ipv6AddrRange::new( 871 Ipv6Addr::from_str("fd00::").unwrap(), 872 Ipv6Addr::from_str("fd00::3").unwrap(), 873 ); 874 assert_eq!(i.size_hint(), (4, Some(4))); 875 876 // Size Hint: a range where size clearly overflows usize 877 let i = Ipv6AddrRange::new( 878 Ipv6Addr::from_str("::").unwrap(), 879 Ipv6Addr::from_str("8000::").unwrap(), 880 ); 881 assert_eq!(i.size_hint(), (std::usize::MAX, None)); 882 883 // Min, Max, Last 884 let i = Ipv4AddrRange::new( 885 Ipv4Addr::from_str("10.0.0.0").unwrap(), 886 Ipv4Addr::from_str("10.0.0.3").unwrap() 887 ); 888 assert_eq!(Iterator::min(i), Some(Ipv4Addr::from_str("10.0.0.0").unwrap())); 889 assert_eq!(Iterator::max(i), Some(Ipv4Addr::from_str("10.0.0.3").unwrap())); 890 assert_eq!(i.last(), Some(Ipv4Addr::from_str("10.0.0.3").unwrap())); 891 892 let i = Ipv6AddrRange::new( 893 Ipv6Addr::from_str("fd00::").unwrap(), 894 Ipv6Addr::from_str("fd00::3").unwrap(), 895 ); 896 assert_eq!(Iterator::min(i), Some(Ipv6Addr::from_str("fd00::").unwrap())); 897 assert_eq!(Iterator::max(i), Some(Ipv6Addr::from_str("fd00::3").unwrap())); 898 assert_eq!(i.last(), Some(Ipv6Addr::from_str("fd00::3").unwrap())); 899 900 // Nth 901 let i = Ipv4AddrRange::new( 902 Ipv4Addr::from_str("10.0.0.0").unwrap(), 903 Ipv4Addr::from_str("10.0.0.3").unwrap() 904 ); 905 assert_eq!(i.clone().nth(0), Some(Ipv4Addr::from_str("10.0.0.0").unwrap())); 906 assert_eq!(i.clone().nth(3), Some(Ipv4Addr::from_str("10.0.0.3").unwrap())); 907 assert_eq!(i.clone().nth(4), None); 908 assert_eq!(i.clone().nth(99), None); 909 let mut i2 = i.clone(); 910 assert_eq!(i2.nth(1), Some(Ipv4Addr::from_str("10.0.0.1").unwrap())); 911 assert_eq!(i2.nth(1), Some(Ipv4Addr::from_str("10.0.0.3").unwrap())); 912 assert_eq!(i2.nth(0), None); 913 let mut i3 = i.clone(); 914 assert_eq!(i3.nth(99), None); 915 assert_eq!(i3.next(), None); 916 917 let i = Ipv6AddrRange::new( 918 Ipv6Addr::from_str("fd00::").unwrap(), 919 Ipv6Addr::from_str("fd00::3").unwrap(), 920 ); 921 assert_eq!(i.clone().nth(0), Some(Ipv6Addr::from_str("fd00::").unwrap())); 922 assert_eq!(i.clone().nth(3), Some(Ipv6Addr::from_str("fd00::3").unwrap())); 923 assert_eq!(i.clone().nth(4), None); 924 assert_eq!(i.clone().nth(99), None); 925 let mut i2 = i.clone(); 926 assert_eq!(i2.nth(1), Some(Ipv6Addr::from_str("fd00::1").unwrap())); 927 assert_eq!(i2.nth(1), Some(Ipv6Addr::from_str("fd00::3").unwrap())); 928 assert_eq!(i2.nth(0), None); 929 let mut i3 = i.clone(); 930 assert_eq!(i3.nth(99), None); 931 assert_eq!(i3.next(), None); 932 933 // Nth Back 934 let i = Ipv4AddrRange::new( 935 Ipv4Addr::from_str("10.0.0.0").unwrap(), 936 Ipv4Addr::from_str("10.0.0.3").unwrap() 937 ); 938 assert_eq!(i.clone().nth_back(0), Some(Ipv4Addr::from_str("10.0.0.3").unwrap())); 939 assert_eq!(i.clone().nth_back(3), Some(Ipv4Addr::from_str("10.0.0.0").unwrap())); 940 assert_eq!(i.clone().nth_back(4), None); 941 assert_eq!(i.clone().nth_back(99), None); 942 let mut i2 = i.clone(); 943 assert_eq!(i2.nth_back(1), Some(Ipv4Addr::from_str("10.0.0.2").unwrap())); 944 assert_eq!(i2.nth_back(1), Some(Ipv4Addr::from_str("10.0.0.0").unwrap())); 945 assert_eq!(i2.nth_back(0), None); 946 let mut i3 = i.clone(); 947 assert_eq!(i3.nth_back(99), None); 948 assert_eq!(i3.next(), None); 949 950 let i = Ipv6AddrRange::new( 951 Ipv6Addr::from_str("fd00::").unwrap(), 952 Ipv6Addr::from_str("fd00::3").unwrap(), 953 ); 954 assert_eq!(i.clone().nth_back(0), Some(Ipv6Addr::from_str("fd00::3").unwrap())); 955 assert_eq!(i.clone().nth_back(3), Some(Ipv6Addr::from_str("fd00::").unwrap())); 956 assert_eq!(i.clone().nth_back(4), None); 957 assert_eq!(i.clone().nth_back(99), None); 958 let mut i2 = i.clone(); 959 assert_eq!(i2.nth_back(1), Some(Ipv6Addr::from_str("fd00::2").unwrap())); 960 assert_eq!(i2.nth_back(1), Some(Ipv6Addr::from_str("fd00::").unwrap())); 961 assert_eq!(i2.nth_back(0), None); 962 let mut i3 = i.clone(); 963 assert_eq!(i3.nth_back(99), None); 964 assert_eq!(i3.next(), None); 965 } 966 }