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, src:Ipv4Addr::new(a:0, b:0, c:0, d:1))
242 }
243 fn replace_zero(&mut self) -> Self {
244 mem::replace(self, src:Ipv4Addr::new(a:0, b:0, c:0, d: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, src:Ipv6Addr::new(a:0, b:0, c:0, d:0, e:0, f:0, g:0, h:1))
257 }
258 fn replace_zero(&mut self) -> Self {
259 mem::replace(self, src:Ipv6Addr::new(a:0, b:0, c:0, d:0, e:0, f:0, g:0, h: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: u64 = 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: &mut Ipv4AddrRange) => a.next_back().map(IpAddr::V4),
662 IpAddrRange::V6(ref mut a: &mut Ipv6AddrRange) => 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: &mut Ipv4AddrRange) => a.nth_back(n).map(IpAddr::V4),
668 IpAddrRange::V6(ref mut a: &mut Ipv6AddrRange) => 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}
996