1use std::cmp::Ordering::{Less, Equal};
8use std::iter::{FusedIterator, DoubleEndedIterator};
9use std::mem;
10use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
11
12pub trait IpAdd<RHS = Self> {
43 type Output;
44 fn saturating_add(self, rhs: RHS) -> Self::Output;
45}
46
47pub trait IpSub<RHS = Self> {
83 type Output;
84 fn saturating_sub(self, rhs: RHS) -> Self::Output;
85}
86
87pub trait IpBitAnd<RHS = Self> {
110 type Output;
111 fn bitand(self, rhs: RHS) -> Self::Output;
112}
113
114pub 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
210pub 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, Ipv4Addr::new(0, 0, 0, 1))
223 }
224 fn replace_zero(&mut self) -> Self {
225 mem::replace(self, Ipv4Addr::new(0, 0, 0, 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, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))
238 }
239 fn replace_zero(&mut self) -> Self {
240 mem::replace(self, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 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#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
283pub enum IpAddrRange {
284 V4(Ipv4AddrRange),
285 V6(Ipv6AddrRange),
286}
287
288#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
309pub struct Ipv4AddrRange {
310 start: Ipv4Addr,
311 end: Ipv4Addr,
312}
313
314#[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 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; 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 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 count + 1
390 },
391 Some(Equal) => 1,
392 _ => 0,
393 }
394 }
395 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(const_err)]
473 #[allow(arithmetic_overflow)]
474 fn count(self) -> usize {
475 match self.start.partial_cmp(&self.end) {
476 Some(Less) => {
477 let count: u32 = self.end.saturating_sub(self.start);
480
481 if count <= std::usize::MAX as u32 {
486 count as usize + 1
487 } else {
489 std::usize::MAX + 2 + count as usize
491 }
492 },
493 Some(Equal) => 1,
494 _ => 0
495 }
496 }
497
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
505 fn max(self) -> Option<Self::Item> {
506 self.last()
507 }
508
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
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
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
544impl Iterator for Ipv6AddrRange {
545 type Item = Ipv6Addr;
546
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)]
563 fn count(self) -> usize {
564 let count = self.count_u128();
565 if count <= std::usize::MAX as u128 {
567 count as usize
568 } else {
570 std::usize::MAX + 1 + count as usize
572 }
573 }
574
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
582 fn max(self) -> Option<Self::Item> {
583 self.last()
584 }
585
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
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 } else {
612 let nth = self.start.saturating_add(n);
613 self.start = nth.add_one();
614 Some(nth)
615 }
616 }
617
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
633impl DoubleEndedIterator for IpAddrRange {
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 }
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
648impl DoubleEndedIterator for Ipv4AddrRange {
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 }
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
680impl DoubleEndedIterator for Ipv6AddrRange {
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 }
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 } 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
721impl FusedIterator for IpAddrRange {}
722impl FusedIterator for Ipv4AddrRange {}
723impl FusedIterator for Ipv6AddrRange {}
724
725#[cfg(test)]
726mod tests {
727 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
728 use std::str::FromStr;
729 use super::*;
730
731 #[test]
732 fn test_ipaddrrange() {
733 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 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 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 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 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 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 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 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}