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