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
7use std::cmp::Ordering::{Less, Equal};
8use std::iter::{FusedIterator, DoubleEndedIterator};
9use std::mem;
10use 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/// ```
42pub trait IpAdd<RHS = Self> {
43 type Output;
44 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/// ```
82pub trait IpSub<RHS = Self> {
83 type Output;
84 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/// ```
109pub trait IpBitAnd<RHS = Self> {
110 type Output;
111 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/// ```
136pub trait IpBitOr<RHS = Self> {
137 type Output;
138 fn bitor(self, rhs: RHS) -> Self::Output;
139}
140
141macro_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
155macro_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
169ip_add_impl!(Ipv4Addr, u32, Ipv4Addr, u32);
170ip_add_impl!(Ipv6Addr, u128, Ipv6Addr, u128);
171
172ip_sub_impl!(Ipv4Addr, Ipv4Addr, u32, u32);
173ip_sub_impl!(Ipv4Addr, u32, Ipv4Addr, u32);
174ip_sub_impl!(Ipv6Addr, Ipv6Addr, u128, u128);
175ip_sub_impl!(Ipv6Addr, u128, Ipv6Addr, u128);
176
177macro_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
203ip_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.
213pub trait IpStep {
214 fn replace_one(&mut self) -> Self;
215 fn replace_zero(&mut self) -> Self;
216 fn add_one(&self) -> Self;
217 fn sub_one(&self) -> Self;
218}
219
220impl IpStep for Ipv4Addr {
221 fn replace_one(&mut self) -> Self {
222 mem::replace(self, src:Ipv4Addr::new(a:0, b:0, c:0, d:1))
223 }
224 fn replace_zero(&mut self) -> Self {
225 mem::replace(self, src:Ipv4Addr::new(a:0, b:0, c:0, d:0))
226 }
227 fn add_one(&self) -> Self {
228 self.saturating_add(1)
229 }
230 fn sub_one(&self) -> Self {
231 self.saturating_sub(1)
232 }
233}
234
235impl IpStep for Ipv6Addr {
236 fn replace_one(&mut self) -> Self {
237 mem::replace(self, src:Ipv6Addr::new(a:0, b:0, c:0, d:0, e:0, f:0, g:0, h:1))
238 }
239 fn replace_zero(&mut self) -> Self {
240 mem::replace(self, src:Ipv6Addr::new(a:0, b:0, c:0, d:0, e:0, f:0, g:0, h:0))
241 }
242 fn add_one(&self) -> Self {
243 self.saturating_add(1)
244 }
245 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)]
283pub 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)]
309pub 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)]
335pub struct Ipv6AddrRange {
336 start: Ipv6Addr,
337 end: Ipv6Addr,
338}
339
340impl From<Ipv4AddrRange> for IpAddrRange {
341 fn from(i: Ipv4AddrRange) -> IpAddrRange {
342 IpAddrRange::V4(i)
343 }
344}
345
346impl From<Ipv6AddrRange> for IpAddrRange {
347 fn from(i: Ipv6AddrRange) -> IpAddrRange {
348 IpAddrRange::V6(i)
349 }
350}
351
352impl Ipv4AddrRange {
353 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.
361 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: u64 = count as u64 + 1; // Never overflows
366 count
367 },
368 Some(Equal) => 1,
369 _ => 0,
370 }
371 }
372}
373
374impl Ipv6AddrRange {
375 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
384 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
396 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
402impl Iterator for IpAddrRange {
403 type Item = IpAddr;
404
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
412 fn count(self) -> usize {
413 match self {
414 IpAddrRange::V4(a) => a.count(),
415 IpAddrRange::V6(a) => a.count(),
416 }
417 }
418
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
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
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
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
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
455impl Iterator for Ipv4AddrRange {
456 type Item = Ipv4Addr;
457
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(arithmetic_overflow)]
473 fn count(self) -> usize {
474 match self.start.partial_cmp(&self.end) {
475 Some(Less) => {
476 // Adding one here might overflow u32.
477 // Instead, wait until after converted to usize
478 let count: u32 = self.end.saturating_sub(self.start);
479
480 // usize might only be 16 bits,
481 // so need to explicitly check for overflow.
482 // 'usize::MAX as u32' is okay here - if usize is 64 bits,
483 // value truncates to u32::MAX
484 if count <= std::usize::MAX as u32 {
485 count as usize + 1
486 // count overflows usize
487 } else {
488 // emulate standard overflow/panic behavior
489 std::usize::MAX + 2 + count as usize
490 }
491 },
492 Some(Equal) => 1,
493 _ => 0
494 }
495 }
496
497 fn last(self) -> Option<Self::Item> {
498 match self.start.partial_cmp(&self.end) {
499 Some(Less) | Some(Equal) => Some(self.end),
500 _ => None,
501 }
502 }
503
504 fn max(self) -> Option<Self::Item> {
505 self.last()
506 }
507
508 fn min(self) -> Option<Self::Item> {
509 match self.start.partial_cmp(&self.end) {
510 Some(Less) | Some(Equal) => Some(self.start),
511 _ => None
512 }
513 }
514
515 fn nth(&mut self, n: usize) -> Option<Self::Item> {
516 let n = n as u64;
517 let count = self.count_u64();
518 if n >= count {
519 self.end.replace_zero();
520 self.start.replace_one();
521 None
522 } else if n == count - 1 {
523 self.start.replace_one();
524 Some(self.end.replace_zero())
525 } else {
526 let nth = self.start.saturating_add(n as u32);
527 self.start = nth.add_one();
528 Some(nth)
529 }
530 }
531
532 fn size_hint(&self) -> (usize, Option<usize>) {
533 let count = self.count_u64();
534 if count > std::usize::MAX as u64 {
535 (std::usize::MAX, None)
536 } else {
537 let count = count as usize;
538 (count, Some(count))
539 }
540 }
541}
542
543impl Iterator for Ipv6AddrRange {
544 type Item = Ipv6Addr;
545
546 fn next(&mut self) -> Option<Self::Item> {
547 match self.start.partial_cmp(&self.end) {
548 Some(Less) => {
549 let next = self.start.add_one();
550 Some(mem::replace(&mut self.start, next))
551 },
552 Some(Equal) => {
553 self.end.replace_zero();
554 Some(self.start.replace_one())
555 },
556 _ => None,
557 }
558 }
559
560 #[allow(arithmetic_overflow)]
561 fn count(self) -> usize {
562 let count = self.count_u128();
563 // count fits in usize
564 if count <= std::usize::MAX as u128 {
565 count as usize
566 // count does not fit in usize
567 } else {
568 // emulate standard overflow/panic behavior
569 std::usize::MAX + 1 + count as usize
570 }
571 }
572
573 fn last(self) -> Option<Self::Item> {
574 match self.start.partial_cmp(&self.end) {
575 Some(Less) | Some(Equal) => Some(self.end),
576 _ => None,
577 }
578 }
579
580 fn max(self) -> Option<Self::Item> {
581 self.last()
582 }
583
584 fn min(self) -> Option<Self::Item> {
585 match self.start.partial_cmp(&self.end) {
586 Some(Less) | Some(Equal) => Some(self.start),
587 _ => None
588 }
589 }
590
591 fn nth(&mut self, n: usize) -> Option<Self::Item> {
592 let n = n as u128;
593 if self.can_count_u128() {
594 let count = self.count_u128();
595 if n >= count {
596 self.end.replace_zero();
597 self.start.replace_one();
598 None
599 } else if n == count - 1 {
600 self.start.replace_one();
601 Some(self.end.replace_zero())
602 } else {
603 let nth = self.start.saturating_add(n);
604 self.start = nth.add_one();
605 Some(nth)
606 }
607 // count overflows u128; n is 64-bits at most.
608 // therefore, n can never exceed count
609 } else {
610 let nth = self.start.saturating_add(n);
611 self.start = nth.add_one();
612 Some(nth)
613 }
614 }
615
616 fn size_hint(&self) -> (usize, Option<usize>) {
617 if self.can_count_u128() {
618 let count = self.count_u128();
619 if count > std::usize::MAX as u128 {
620 (std::usize::MAX, None)
621 } else {
622 let count = count as usize;
623 (count, Some(count))
624 }
625 } else {
626 (std::usize::MAX, None)
627 }
628 }
629}
630
631impl DoubleEndedIterator for IpAddrRange {
632 fn next_back(&mut self) -> Option<Self::Item> {
633 match *self {
634 IpAddrRange::V4(ref mut a: &mut Ipv4AddrRange) => a.next_back().map(IpAddr::V4),
635 IpAddrRange::V6(ref mut a: &mut Ipv6AddrRange) => a.next_back().map(IpAddr::V6),
636 }
637 }
638 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
639 match *self {
640 IpAddrRange::V4(ref mut a: &mut Ipv4AddrRange) => a.nth_back(n).map(IpAddr::V4),
641 IpAddrRange::V6(ref mut a: &mut Ipv6AddrRange) => a.nth_back(n).map(IpAddr::V6),
642 }
643 }
644}
645
646impl DoubleEndedIterator for Ipv4AddrRange {
647 fn next_back(&mut self) -> Option<Self::Item> {
648 match self.start.partial_cmp(&self.end) {
649 Some(Less) => {
650 let next_back = self.end.sub_one();
651 Some(mem::replace(&mut self.end, next_back))
652 },
653 Some(Equal) => {
654 self.end.replace_zero();
655 Some(self.start.replace_one())
656 },
657 _ => None
658 }
659 }
660 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
661 let n = n as u64;
662 let count = self.count_u64();
663 if n >= count {
664 self.end.replace_zero();
665 self.start.replace_one();
666 None
667 } else if n == count - 1 {
668 self.end.replace_zero();
669 Some(self.start.replace_one())
670 } else {
671 let nth_back = self.end.saturating_sub(n as u32);
672 self.end = nth_back.sub_one();
673 Some(nth_back)
674 }
675 }
676}
677
678impl DoubleEndedIterator for Ipv6AddrRange {
679 fn next_back(&mut self) -> Option<Self::Item> {
680 match self.start.partial_cmp(&self.end) {
681 Some(Less) => {
682 let next_back = self.end.sub_one();
683 Some(mem::replace(&mut self.end, next_back))
684 },
685 Some(Equal) => {
686 self.end.replace_zero();
687 Some(self.start.replace_one())
688 },
689 _ => None
690 }
691 }
692 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
693 let n = n as u128;
694 if self.can_count_u128() {
695 let count = self.count_u128();
696 if n >= count {
697 self.end.replace_zero();
698 self.start.replace_one();
699 None
700 }
701 else if n == count - 1 {
702 self.end.replace_zero();
703 Some(self.start.replace_one())
704 } else {
705 let nth_back = self.end.saturating_sub(n);
706 self.end = nth_back.sub_one();
707 Some(nth_back)
708 }
709 // count overflows u128; n is 64-bits at most.
710 // therefore, n can never exceed count
711 } else {
712 let nth_back = self.end.saturating_sub(n);
713 self.end = nth_back.sub_one();
714 Some(nth_back)
715 }
716 }
717}
718
719impl FusedIterator for IpAddrRange {}
720impl FusedIterator for Ipv4AddrRange {}
721impl FusedIterator for Ipv6AddrRange {}
722
723#[cfg(test)]
724mod tests {
725 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
726 use std::str::FromStr;
727 use super::*;
728
729 #[test]
730 fn test_ipaddrrange() {
731 // Next, Next-Back
732 let i = Ipv4AddrRange::new(
733 Ipv4Addr::from_str("10.0.0.0").unwrap(),
734 Ipv4Addr::from_str("10.0.0.3").unwrap()
735 );
736
737 assert_eq!(i.collect::<Vec<Ipv4Addr>>(), vec![
738 Ipv4Addr::from_str("10.0.0.0").unwrap(),
739 Ipv4Addr::from_str("10.0.0.1").unwrap(),
740 Ipv4Addr::from_str("10.0.0.2").unwrap(),
741 Ipv4Addr::from_str("10.0.0.3").unwrap(),
742 ]);
743
744 let mut v = i.collect::<Vec<_>>();
745 v.reverse();
746 assert_eq!(v, i.rev().collect::<Vec<_>>());
747
748 let i = Ipv4AddrRange::new(
749 Ipv4Addr::from_str("255.255.255.254").unwrap(),
750 Ipv4Addr::from_str("255.255.255.255").unwrap()
751 );
752
753 assert_eq!(i.collect::<Vec<Ipv4Addr>>(), vec![
754 Ipv4Addr::from_str("255.255.255.254").unwrap(),
755 Ipv4Addr::from_str("255.255.255.255").unwrap(),
756 ]);
757
758 let i = Ipv6AddrRange::new(
759 Ipv6Addr::from_str("fd00::").unwrap(),
760 Ipv6Addr::from_str("fd00::3").unwrap(),
761 );
762
763 assert_eq!(i.collect::<Vec<Ipv6Addr>>(), vec![
764 Ipv6Addr::from_str("fd00::").unwrap(),
765 Ipv6Addr::from_str("fd00::1").unwrap(),
766 Ipv6Addr::from_str("fd00::2").unwrap(),
767 Ipv6Addr::from_str("fd00::3").unwrap(),
768 ]);
769
770 let mut v = i.collect::<Vec<_>>();
771 v.reverse();
772 assert_eq!(v, i.rev().collect::<Vec<_>>());
773
774 let i = Ipv6AddrRange::new(
775 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(),
776 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(),
777 );
778
779 assert_eq!(i.collect::<Vec<Ipv6Addr>>(), vec![
780 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(),
781 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(),
782 ]);
783
784 let i = IpAddrRange::from(Ipv4AddrRange::new(
785 Ipv4Addr::from_str("10.0.0.0").unwrap(),
786 Ipv4Addr::from_str("10.0.0.3").unwrap(),
787 ));
788
789 assert_eq!(i.collect::<Vec<IpAddr>>(), vec![
790 IpAddr::from_str("10.0.0.0").unwrap(),
791 IpAddr::from_str("10.0.0.1").unwrap(),
792 IpAddr::from_str("10.0.0.2").unwrap(),
793 IpAddr::from_str("10.0.0.3").unwrap(),
794 ]);
795
796 let mut v = i.collect::<Vec<_>>();
797 v.reverse();
798 assert_eq!(v, i.rev().collect::<Vec<_>>());
799
800 let i = IpAddrRange::from(Ipv4AddrRange::new(
801 Ipv4Addr::from_str("255.255.255.254").unwrap(),
802 Ipv4Addr::from_str("255.255.255.255").unwrap()
803 ));
804
805 assert_eq!(i.collect::<Vec<IpAddr>>(), vec![
806 IpAddr::from_str("255.255.255.254").unwrap(),
807 IpAddr::from_str("255.255.255.255").unwrap(),
808 ]);
809
810 let i = IpAddrRange::from(Ipv6AddrRange::new(
811 Ipv6Addr::from_str("fd00::").unwrap(),
812 Ipv6Addr::from_str("fd00::3").unwrap(),
813 ));
814
815 assert_eq!(i.collect::<Vec<IpAddr>>(), vec![
816 IpAddr::from_str("fd00::").unwrap(),
817 IpAddr::from_str("fd00::1").unwrap(),
818 IpAddr::from_str("fd00::2").unwrap(),
819 IpAddr::from_str("fd00::3").unwrap(),
820 ]);
821
822 let mut v = i.collect::<Vec<_>>();
823 v.reverse();
824 assert_eq!(v, i.rev().collect::<Vec<_>>());
825
826 let i = IpAddrRange::from(Ipv6AddrRange::new(
827 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(),
828 Ipv6Addr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(),
829 ));
830
831 assert_eq!(i.collect::<Vec<IpAddr>>(), vec![
832 IpAddr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe").unwrap(),
833 IpAddr::from_str("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff").unwrap(),
834 ]);
835
836 // #11 (infinite iterator when start and stop are 0)
837 let zero4 = Ipv4Addr::from_str("0.0.0.0").unwrap();
838 let zero6 = Ipv6Addr::from_str("::").unwrap();
839
840 let mut i = Ipv4AddrRange::new(zero4, zero4);
841 assert_eq!(Some(zero4), i.next());
842 assert_eq!(None, i.next());
843
844 let mut i = Ipv6AddrRange::new(zero6, zero6);
845 assert_eq!(Some(zero6), i.next());
846 assert_eq!(None, i.next());
847
848 // Count
849 let i = Ipv4AddrRange::new(
850 Ipv4Addr::from_str("10.0.0.0").unwrap(),
851 Ipv4Addr::from_str("10.0.0.3").unwrap()
852 );
853 assert_eq!(i.count(), 4);
854
855 let i = Ipv6AddrRange::new(
856 Ipv6Addr::from_str("fd00::").unwrap(),
857 Ipv6Addr::from_str("fd00::3").unwrap(),
858 );
859 assert_eq!(i.count(), 4);
860
861 // Size Hint
862 let i = Ipv4AddrRange::new(
863 Ipv4Addr::from_str("10.0.0.0").unwrap(),
864 Ipv4Addr::from_str("10.0.0.3").unwrap()
865 );
866 assert_eq!(i.size_hint(), (4, Some(4)));
867
868 let i = Ipv6AddrRange::new(
869 Ipv6Addr::from_str("fd00::").unwrap(),
870 Ipv6Addr::from_str("fd00::3").unwrap(),
871 );
872 assert_eq!(i.size_hint(), (4, Some(4)));
873
874 // Size Hint: a range where size clearly overflows usize
875 let i = Ipv6AddrRange::new(
876 Ipv6Addr::from_str("::").unwrap(),
877 Ipv6Addr::from_str("8000::").unwrap(),
878 );
879 assert_eq!(i.size_hint(), (std::usize::MAX, None));
880
881 // Min, Max, Last
882 let i = Ipv4AddrRange::new(
883 Ipv4Addr::from_str("10.0.0.0").unwrap(),
884 Ipv4Addr::from_str("10.0.0.3").unwrap()
885 );
886 assert_eq!(Iterator::min(i), Some(Ipv4Addr::from_str("10.0.0.0").unwrap()));
887 assert_eq!(Iterator::max(i), Some(Ipv4Addr::from_str("10.0.0.3").unwrap()));
888 assert_eq!(i.last(), Some(Ipv4Addr::from_str("10.0.0.3").unwrap()));
889
890 let i = Ipv6AddrRange::new(
891 Ipv6Addr::from_str("fd00::").unwrap(),
892 Ipv6Addr::from_str("fd00::3").unwrap(),
893 );
894 assert_eq!(Iterator::min(i), Some(Ipv6Addr::from_str("fd00::").unwrap()));
895 assert_eq!(Iterator::max(i), Some(Ipv6Addr::from_str("fd00::3").unwrap()));
896 assert_eq!(i.last(), Some(Ipv6Addr::from_str("fd00::3").unwrap()));
897
898 // Nth
899 let i = Ipv4AddrRange::new(
900 Ipv4Addr::from_str("10.0.0.0").unwrap(),
901 Ipv4Addr::from_str("10.0.0.3").unwrap()
902 );
903 assert_eq!(i.clone().nth(0), Some(Ipv4Addr::from_str("10.0.0.0").unwrap()));
904 assert_eq!(i.clone().nth(3), Some(Ipv4Addr::from_str("10.0.0.3").unwrap()));
905 assert_eq!(i.clone().nth(4), None);
906 assert_eq!(i.clone().nth(99), None);
907 let mut i2 = i.clone();
908 assert_eq!(i2.nth(1), Some(Ipv4Addr::from_str("10.0.0.1").unwrap()));
909 assert_eq!(i2.nth(1), Some(Ipv4Addr::from_str("10.0.0.3").unwrap()));
910 assert_eq!(i2.nth(0), None);
911 let mut i3 = i.clone();
912 assert_eq!(i3.nth(99), None);
913 assert_eq!(i3.next(), None);
914
915 let i = Ipv6AddrRange::new(
916 Ipv6Addr::from_str("fd00::").unwrap(),
917 Ipv6Addr::from_str("fd00::3").unwrap(),
918 );
919 assert_eq!(i.clone().nth(0), Some(Ipv6Addr::from_str("fd00::").unwrap()));
920 assert_eq!(i.clone().nth(3), Some(Ipv6Addr::from_str("fd00::3").unwrap()));
921 assert_eq!(i.clone().nth(4), None);
922 assert_eq!(i.clone().nth(99), None);
923 let mut i2 = i.clone();
924 assert_eq!(i2.nth(1), Some(Ipv6Addr::from_str("fd00::1").unwrap()));
925 assert_eq!(i2.nth(1), Some(Ipv6Addr::from_str("fd00::3").unwrap()));
926 assert_eq!(i2.nth(0), None);
927 let mut i3 = i.clone();
928 assert_eq!(i3.nth(99), None);
929 assert_eq!(i3.next(), None);
930
931 // Nth Back
932 let i = Ipv4AddrRange::new(
933 Ipv4Addr::from_str("10.0.0.0").unwrap(),
934 Ipv4Addr::from_str("10.0.0.3").unwrap()
935 );
936 assert_eq!(i.clone().nth_back(0), Some(Ipv4Addr::from_str("10.0.0.3").unwrap()));
937 assert_eq!(i.clone().nth_back(3), Some(Ipv4Addr::from_str("10.0.0.0").unwrap()));
938 assert_eq!(i.clone().nth_back(4), None);
939 assert_eq!(i.clone().nth_back(99), None);
940 let mut i2 = i.clone();
941 assert_eq!(i2.nth_back(1), Some(Ipv4Addr::from_str("10.0.0.2").unwrap()));
942 assert_eq!(i2.nth_back(1), Some(Ipv4Addr::from_str("10.0.0.0").unwrap()));
943 assert_eq!(i2.nth_back(0), None);
944 let mut i3 = i.clone();
945 assert_eq!(i3.nth_back(99), None);
946 assert_eq!(i3.next(), None);
947
948 let i = Ipv6AddrRange::new(
949 Ipv6Addr::from_str("fd00::").unwrap(),
950 Ipv6Addr::from_str("fd00::3").unwrap(),
951 );
952 assert_eq!(i.clone().nth_back(0), Some(Ipv6Addr::from_str("fd00::3").unwrap()));
953 assert_eq!(i.clone().nth_back(3), Some(Ipv6Addr::from_str("fd00::").unwrap()));
954 assert_eq!(i.clone().nth_back(4), None);
955 assert_eq!(i.clone().nth_back(99), None);
956 let mut i2 = i.clone();
957 assert_eq!(i2.nth_back(1), Some(Ipv6Addr::from_str("fd00::2").unwrap()));
958 assert_eq!(i2.nth_back(1), Some(Ipv6Addr::from_str("fd00::").unwrap()));
959 assert_eq!(i2.nth_back(0), None);
960 let mut i3 = i.clone();
961 assert_eq!(i3.nth_back(99), None);
962 assert_eq!(i3.next(), None);
963 }
964}
965