ipnet/
ipext.rs

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, 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/// 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 = 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(const_err)]
473    #[allow(arithmetic_overflow)]
474    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
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        // 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
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        // 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
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        // 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
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        // 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}