• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
7 use core::cmp::Ordering::{Less, Equal};
8 use core::iter::{FusedIterator, DoubleEndedIterator};
9 use core::mem;
10 #[cfg(not(feature = "std"))]
11 use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
12 #[cfg(feature = "std")]
13 use 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 /// ```
48 pub trait IpAdd<RHS = Self> {
49     type Output;
saturating_add(self, rhs: RHS) -> Self::Output50     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 /// ```
91 pub trait IpSub<RHS = Self> {
92     type Output;
saturating_sub(self, rhs: RHS) -> Self::Output93     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 /// ```
121 pub trait IpBitAnd<RHS = Self> {
122     type Output;
bitand(self, rhs: RHS) -> Self::Output123     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 /// ```
151 pub trait IpBitOr<RHS = Self> {
152     type Output;
bitor(self, rhs: RHS) -> Self::Output153     fn bitor(self, rhs: RHS) -> Self::Output;
154 }
155 
156 macro_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 
170 macro_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 
184 ip_add_impl!(Ipv4Addr, u32, Ipv4Addr, u32);
185 ip_add_impl!(Ipv6Addr, u128, Ipv6Addr, u128);
186 
187 ip_sub_impl!(Ipv4Addr, Ipv4Addr, u32, u32);
188 ip_sub_impl!(Ipv4Addr, u32, Ipv4Addr, u32);
189 ip_sub_impl!(Ipv6Addr, Ipv6Addr, u128, u128);
190 ip_sub_impl!(Ipv6Addr, u128, Ipv6Addr, u128);
191 
192 macro_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 
218 ip_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.
228 pub trait IpStep {
replace_one(&mut self) -> Self229     fn replace_one(&mut self) -> Self;
replace_zero(&mut self) -> Self230     fn replace_zero(&mut self) -> Self;
add_one(&self) -> Self231     fn add_one(&self) -> Self;
sub_one(&self) -> Self232     fn sub_one(&self) -> Self;
233 }
234 
235 impl IpStep for Ipv4Addr {
replace_one(&mut self) -> Self236     fn replace_one(&mut self) -> Self {
237         mem::replace(self, Ipv4Addr::new(0, 0, 0, 1))
238     }
replace_zero(&mut self) -> Self239     fn replace_zero(&mut self) -> Self {
240         mem::replace(self, Ipv4Addr::new(0, 0, 0, 0))
241     }
add_one(&self) -> Self242     fn add_one(&self) -> Self {
243         self.saturating_add(1)
244     }
sub_one(&self) -> Self245     fn sub_one(&self) -> Self {
246         self.saturating_sub(1)
247     }
248 }
249 
250 impl IpStep for Ipv6Addr {
replace_one(&mut self) -> Self251     fn replace_one(&mut self) -> Self {
252         mem::replace(self, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))
253     }
replace_zero(&mut self) -> Self254     fn replace_zero(&mut self) -> Self {
255         mem::replace(self, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0))
256     }
add_one(&self) -> Self257     fn add_one(&self) -> Self {
258         self.saturating_add(1)
259     }
sub_one(&self) -> Self260     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)]
298 pub 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)]
327 pub 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)]
356 pub struct Ipv6AddrRange {
357     start: Ipv6Addr,
358     end: Ipv6Addr,
359 }
360 
361 impl From<Ipv4AddrRange> for IpAddrRange {
from(i: Ipv4AddrRange) -> IpAddrRange362     fn from(i: Ipv4AddrRange) -> IpAddrRange {
363         IpAddrRange::V4(i)
364     }
365 }
366 
367 impl From<Ipv6AddrRange> for IpAddrRange {
from(i: Ipv6AddrRange) -> IpAddrRange368     fn from(i: Ipv6AddrRange) -> IpAddrRange {
369         IpAddrRange::V6(i)
370     }
371 }
372 
373 impl Ipv4AddrRange {
new(start: Ipv4Addr, end: Ipv4Addr) -> Self374     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.
count_u64(&self) -> u64382     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 
395 impl Ipv6AddrRange {
new(start: Ipv6Addr, end: Ipv6Addr) -> Self396     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
count_u128(&self) -> u128405     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
can_count_u128(&self) -> bool417     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 
423 impl Iterator for IpAddrRange {
424     type Item = IpAddr;
425 
next(&mut self) -> Option<Self::Item>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 
count(self) -> usize433     fn count(self) -> usize {
434         match self {
435             IpAddrRange::V4(a) => a.count(),
436             IpAddrRange::V6(a) => a.count(),
437         }
438     }
439 
last(self) -> Option<Self::Item>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 
max(self) -> Option<Self::Item>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 
min(self) -> Option<Self::Item>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 
nth(&mut self, n: usize) -> Option<Self::Item>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 
size_hint(&self) -> (usize, Option<usize>)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 
476 impl Iterator for Ipv4AddrRange {
477     type Item = Ipv4Addr;
478 
next(&mut self) -> Option<Self::Item>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)]
count(self) -> usize494     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 
last(self) -> Option<Self::Item>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 
max(self) -> Option<Self::Item>525     fn max(self) -> Option<Self::Item> {
526         self.last()
527     }
528 
min(self) -> Option<Self::Item>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 
nth(&mut self, n: usize) -> Option<Self::Item>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 
size_hint(&self) -> (usize, Option<usize>)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 
564 impl Iterator for Ipv6AddrRange {
565     type Item = Ipv6Addr;
566 
next(&mut self) -> Option<Self::Item>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)]
count(self) -> usize582     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 
last(self) -> Option<Self::Item>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 
max(self) -> Option<Self::Item>601     fn max(self) -> Option<Self::Item> {
602         self.last()
603     }
604 
min(self) -> Option<Self::Item>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 
nth(&mut self, n: usize) -> Option<Self::Item>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 
size_hint(&self) -> (usize, Option<usize>)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 
652 impl DoubleEndedIterator for IpAddrRange {
next_back(&mut self) -> Option<Self::Item>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     }
nth_back(&mut self, n: usize) -> Option<Self::Item>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 
667 impl DoubleEndedIterator for Ipv4AddrRange {
next_back(&mut self) -> Option<Self::Item>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     }
nth_back(&mut self, n: usize) -> Option<Self::Item>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 
699 impl DoubleEndedIterator for Ipv6AddrRange {
next_back(&mut self) -> Option<Self::Item>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     }
nth_back(&mut self, n: usize) -> Option<Self::Item>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 
740 impl FusedIterator for IpAddrRange {}
741 impl FusedIterator for Ipv4AddrRange {}
742 impl FusedIterator for Ipv6AddrRange {}
743 
744 #[cfg(test)]
745 mod 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]
test_ipaddrrange()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 }
990