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