Coverage Report

Created: 2025-07-23 07:04

/rust/registry/src/index.crates.io-6f17d22bba15001f/ipnet-2.11.0/src/ipext.rs
Line
Count
Source (jump to first uncovered line)
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;
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
/// ```
91
pub 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
/// ```
121
pub 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
/// ```
151
pub trait IpBitOr<RHS = Self> {
152
    type Output;
153
    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
0
            fn saturating_add(self, rhs: $rhs) -> $output {
162
0
                let lhs: $inner = self.into();
163
0
                let rhs: $inner = rhs.into();
164
0
                (lhs.saturating_add(rhs.into())).into()
165
0
            }
Unexecuted instantiation: <core::net::ip_addr::Ipv4Addr as ipnet::ipext::IpAdd<u32>>::saturating_add
Unexecuted instantiation: <core::net::ip_addr::Ipv6Addr as ipnet::ipext::IpAdd<u128>>::saturating_add
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
0
            fn saturating_sub(self, rhs: $rhs) -> $output {
176
0
                let lhs: $inner = self.into();
177
0
                let rhs: $inner = rhs.into();
178
0
                (lhs.saturating_sub(rhs.into())).into()
179
0
            }
Unexecuted instantiation: <core::net::ip_addr::Ipv4Addr as ipnet::ipext::IpSub>::saturating_sub
Unexecuted instantiation: <core::net::ip_addr::Ipv4Addr as ipnet::ipext::IpSub<u32>>::saturating_sub
Unexecuted instantiation: <core::net::ip_addr::Ipv6Addr as ipnet::ipext::IpSub>::saturating_sub
Unexecuted instantiation: <core::net::ip_addr::Ipv6Addr as ipnet::ipext::IpSub<u128>>::saturating_sub
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
0
            fn bitand(self, rhs: $rhs) -> $lhs {
199
0
                let lhs: $t = self.into();
200
0
                let rhs: $t = rhs.into();
201
0
                (lhs & rhs).into()
202
0
            }
Unexecuted instantiation: <core::net::ip_addr::Ipv4Addr as ipnet::ipext::IpBitAnd>::bitand
Unexecuted instantiation: <core::net::ip_addr::Ipv4Addr as ipnet::ipext::IpBitAnd<u32>>::bitand
Unexecuted instantiation: <core::net::ip_addr::Ipv6Addr as ipnet::ipext::IpBitAnd>::bitand
Unexecuted instantiation: <core::net::ip_addr::Ipv6Addr as ipnet::ipext::IpBitAnd<u128>>::bitand
203
        }
204
205
        impl IpBitOr<$rhs> for $lhs {
206
            type Output = $lhs;
207
208
0
            fn bitor(self, rhs: $rhs) -> $lhs {
209
0
                let lhs: $t = self.into();
210
0
                let rhs: $t = rhs.into();
211
0
                (lhs | rhs).into()
212
0
            }
Unexecuted instantiation: <core::net::ip_addr::Ipv4Addr as ipnet::ipext::IpBitOr>::bitor
Unexecuted instantiation: <core::net::ip_addr::Ipv4Addr as ipnet::ipext::IpBitOr<u32>>::bitor
Unexecuted instantiation: <core::net::ip_addr::Ipv6Addr as ipnet::ipext::IpBitOr>::bitor
Unexecuted instantiation: <core::net::ip_addr::Ipv6Addr as ipnet::ipext::IpBitOr<u128>>::bitor
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 {
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
235
impl IpStep for Ipv4Addr {
236
0
    fn replace_one(&mut self) -> Self {
237
0
        mem::replace(self, Ipv4Addr::new(0, 0, 0, 1))
238
0
    }
239
0
    fn replace_zero(&mut self) -> Self {
240
0
        mem::replace(self, Ipv4Addr::new(0, 0, 0, 0))
241
0
    }
242
0
    fn add_one(&self) -> Self {
243
0
        self.saturating_add(1)
244
0
    }
245
0
    fn sub_one(&self) -> Self {
246
0
        self.saturating_sub(1)
247
0
    }
248
}
249
250
impl IpStep for Ipv6Addr {
251
0
    fn replace_one(&mut self) -> Self {
252
0
        mem::replace(self, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1))
253
0
    }
254
0
    fn replace_zero(&mut self) -> Self {
255
0
        mem::replace(self, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0))
256
0
    }
257
0
    fn add_one(&self) -> Self {
258
0
        self.saturating_add(1)
259
0
    }
260
0
    fn sub_one(&self) -> Self {
261
0
        self.saturating_sub(1)
262
0
    }
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 {
362
0
    fn from(i: Ipv4AddrRange) -> IpAddrRange {
363
0
        IpAddrRange::V4(i)
364
0
    }
365
}
366
367
impl From<Ipv6AddrRange> for IpAddrRange {
368
0
    fn from(i: Ipv6AddrRange) -> IpAddrRange {
369
0
        IpAddrRange::V6(i)
370
0
    }
371
}
372
373
impl Ipv4AddrRange {
374
0
    pub fn new(start: Ipv4Addr, end: Ipv4Addr) -> Self {
375
0
        Ipv4AddrRange {
376
0
            start: start,
377
0
            end: end,
378
0
        }
379
0
    }
380
    /// Counts the number of Ipv4Addr in this range.
381
    /// This method will never overflow or panic.
382
0
    fn count_u64(&self) -> u64 {
383
0
        match self.start.partial_cmp(&self.end) {
384
            Some(Less) => {
385
0
                let count: u32 = self.end.saturating_sub(self.start);
386
0
                let count = count as u64 + 1; // Never overflows
387
0
                count
388
            },
389
0
            Some(Equal) => 1,
390
0
            _ => 0,
391
        }
392
0
    }
393
}
394
395
impl Ipv6AddrRange {
396
0
    pub fn new(start: Ipv6Addr, end: Ipv6Addr) -> Self {
397
0
        Ipv6AddrRange {
398
0
            start: start,
399
0
            end: end,
400
0
        }
401
0
    }
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
0
    fn count_u128(&self) -> u128 {
406
0
        match self.start.partial_cmp(&self.end) {
407
            Some(Less) => {
408
0
                let count = self.end.saturating_sub(self.start);
409
0
                // May overflow or panic
410
0
                count + 1
411
            },
412
0
            Some(Equal) => 1,
413
0
            _ => 0,
414
        }
415
0
    }
416
    /// True only if count_u128 does not overflow
417
0
    fn can_count_u128(&self) -> bool {
418
0
        self.start != Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)
419
0
        || self.end != Ipv6Addr::new(0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
420
0
    }
421
}
422
423
impl Iterator for IpAddrRange {
424
    type Item = IpAddr;
425
426
0
    fn next(&mut self) -> Option<Self::Item> {
427
0
        match *self {
428
0
            IpAddrRange::V4(ref mut a) => a.next().map(IpAddr::V4),
429
0
            IpAddrRange::V6(ref mut a) => a.next().map(IpAddr::V6),
430
        }
431
0
    }
432
433
0
    fn count(self) -> usize {
434
0
        match self {
435
0
            IpAddrRange::V4(a) => a.count(),
436
0
            IpAddrRange::V6(a) => a.count(),
437
        }
438
0
    }
439
440
0
    fn last(self) -> Option<Self::Item> {
441
0
        match self {
442
0
            IpAddrRange::V4(a) => a.last().map(IpAddr::V4),
443
0
            IpAddrRange::V6(a) => a.last().map(IpAddr::V6),
444
        }
445
0
    }
446
447
0
    fn max(self) -> Option<Self::Item> {
448
0
        match self {
449
0
            IpAddrRange::V4(a) => Iterator::max(a).map(IpAddr::V4),
450
0
            IpAddrRange::V6(a) => Iterator::max(a).map(IpAddr::V6),
451
        }
452
0
    }
453
454
0
    fn min(self) -> Option<Self::Item> {
455
0
        match self {
456
0
            IpAddrRange::V4(a) => Iterator::min(a).map(IpAddr::V4),
457
0
            IpAddrRange::V6(a) => Iterator::min(a).map(IpAddr::V6),
458
        }
459
0
    }
460
461
0
    fn nth(&mut self, n: usize) -> Option<Self::Item> {
462
0
        match *self {
463
0
            IpAddrRange::V4(ref mut a) => a.nth(n).map(IpAddr::V4),
464
0
            IpAddrRange::V6(ref mut a) => a.nth(n).map(IpAddr::V6),
465
        }
466
0
    }
467
468
0
    fn size_hint(&self) -> (usize, Option<usize>) {
469
0
        match *self {
470
0
            IpAddrRange::V4(ref a) => a.size_hint(),
471
0
            IpAddrRange::V6(ref a) => a.size_hint(),
472
        }
473
0
    }
474
}
475
476
impl Iterator for Ipv4AddrRange {
477
    type Item = Ipv4Addr;
478
479
0
    fn next(&mut self) -> Option<Self::Item> {
480
0
        match self.start.partial_cmp(&self.end) {
481
            Some(Less) => {
482
0
                let next = self.start.add_one();
483
0
                Some(mem::replace(&mut self.start, next))
484
            },
485
            Some(Equal) => {
486
0
                self.end.replace_zero();
487
0
                Some(self.start.replace_one())
488
            },
489
0
            _ => None,
490
        }
491
0
    }
492
493
    #[allow(arithmetic_overflow)]
494
0
    fn count(self) -> usize {
495
0
        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
0
                let count: u32 = self.end.saturating_sub(self.start);
500
0
501
0
                // usize might only be 16 bits,
502
0
                // so need to explicitly check for overflow.
503
0
                // 'usize::MAX as u32' is okay here - if usize is 64 bits,
504
0
                // value truncates to u32::MAX
505
0
                if count <= core::usize::MAX as u32 {
506
0
                    count as usize + 1
507
                // count overflows usize
508
                } else {
509
                    // emulate standard overflow/panic behavior
510
0
                    core::usize::MAX + 2 + count as usize
511
                }
512
            },
513
0
            Some(Equal) => 1,
514
0
            _ => 0
515
        }
516
0
    }
517
518
0
    fn last(self) -> Option<Self::Item> {
519
0
        match self.start.partial_cmp(&self.end) {
520
0
            Some(Less) | Some(Equal) => Some(self.end),
521
0
            _ => None,
522
        }
523
0
    }
524
525
0
    fn max(self) -> Option<Self::Item> {
526
0
        self.last()
527
0
    }
528
529
0
    fn min(self) -> Option<Self::Item> {
530
0
        match self.start.partial_cmp(&self.end) {
531
0
            Some(Less) | Some(Equal) => Some(self.start),
532
0
            _ => None
533
        }
534
0
    }
535
536
0
    fn nth(&mut self, n: usize) -> Option<Self::Item> {
537
0
        let n = n as u64;
538
0
        let count = self.count_u64();
539
0
        if n >= count {
540
0
            self.end.replace_zero();
541
0
            self.start.replace_one();
542
0
            None
543
0
        } else if n == count - 1 {
544
0
            self.start.replace_one();
545
0
            Some(self.end.replace_zero())
546
        } else {
547
0
            let nth = self.start.saturating_add(n as u32);
548
0
            self.start = nth.add_one();
549
0
            Some(nth)
550
        }
551
0
    }
552
553
0
    fn size_hint(&self) -> (usize, Option<usize>) {
554
0
        let count = self.count_u64();
555
0
        if count > core::usize::MAX as u64 {
556
0
            (core::usize::MAX, None)
557
        } else {
558
0
            let count = count as usize;
559
0
            (count, Some(count))
560
        }
561
0
    }
562
}
563
564
impl Iterator for Ipv6AddrRange {
565
    type Item = Ipv6Addr;
566
567
0
    fn next(&mut self) -> Option<Self::Item> {
568
0
        match self.start.partial_cmp(&self.end) {
569
            Some(Less) => {
570
0
                let next = self.start.add_one();
571
0
                Some(mem::replace(&mut self.start, next))
572
            },
573
            Some(Equal) => {
574
0
                self.end.replace_zero();
575
0
                Some(self.start.replace_one())
576
            },
577
0
            _ => None,
578
        }
579
0
    }
580
581
    #[allow(arithmetic_overflow)]
582
0
    fn count(self) -> usize {
583
0
        let count = self.count_u128();
584
0
        // count fits in usize
585
0
        if count <= core::usize::MAX as u128 {
586
0
            count as usize
587
        // count does not fit in usize
588
        } else {
589
            // emulate standard overflow/panic behavior
590
0
            core::usize::MAX + 1 + count as usize
591
        }
592
0
    }
593
594
0
    fn last(self) -> Option<Self::Item> {
595
0
        match self.start.partial_cmp(&self.end) {
596
0
            Some(Less) | Some(Equal) => Some(self.end),
597
0
            _ => None,
598
        }
599
0
    }
600
601
0
    fn max(self) -> Option<Self::Item> {
602
0
        self.last()
603
0
    }
604
605
0
    fn min(self) -> Option<Self::Item> {
606
0
        match self.start.partial_cmp(&self.end) {
607
0
            Some(Less) | Some(Equal) => Some(self.start),
608
0
            _ => None
609
        }
610
0
    }
611
612
0
    fn nth(&mut self, n: usize) -> Option<Self::Item> {
613
0
        let n = n as u128;
614
0
        if self.can_count_u128() {
615
0
            let count = self.count_u128();
616
0
            if n >= count {
617
0
                self.end.replace_zero();
618
0
                self.start.replace_one();
619
0
                None
620
0
            } else if n == count - 1 {
621
0
                self.start.replace_one();
622
0
                Some(self.end.replace_zero())
623
            } else {
624
0
                let nth = self.start.saturating_add(n);
625
0
                self.start = nth.add_one();
626
0
                Some(nth)
627
            }
628
        // count overflows u128; n is 64-bits at most.
629
        // therefore, n can never exceed count
630
        } else {
631
0
            let nth = self.start.saturating_add(n);
632
0
            self.start = nth.add_one();
633
0
            Some(nth)
634
        }
635
0
    }
636
637
0
    fn size_hint(&self) -> (usize, Option<usize>) {
638
0
        if self.can_count_u128() {
639
0
            let count = self.count_u128();
640
0
            if count > core::usize::MAX as u128 {
641
0
                (core::usize::MAX, None)
642
            } else {
643
0
                let count = count as usize;
644
0
                (count, Some(count))
645
            }
646
        } else {
647
0
            (core::usize::MAX, None)
648
        }
649
0
    }
650
}
651
652
impl DoubleEndedIterator for IpAddrRange {
653
0
    fn next_back(&mut self) -> Option<Self::Item> {
654
0
        match *self {
655
0
            IpAddrRange::V4(ref mut a) => a.next_back().map(IpAddr::V4),
656
0
            IpAddrRange::V6(ref mut a) => a.next_back().map(IpAddr::V6),
657
        }
658
0
    }
659
0
    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
660
0
        match *self {
661
0
            IpAddrRange::V4(ref mut a) => a.nth_back(n).map(IpAddr::V4),
662
0
            IpAddrRange::V6(ref mut a) => a.nth_back(n).map(IpAddr::V6),
663
        }
664
0
    }
665
}
666
667
impl DoubleEndedIterator for Ipv4AddrRange {
668
0
    fn next_back(&mut self) -> Option<Self::Item> {
669
0
        match self.start.partial_cmp(&self.end) {
670
            Some(Less) => {
671
0
                let next_back = self.end.sub_one();
672
0
                Some(mem::replace(&mut self.end, next_back))
673
            },
674
            Some(Equal) => {
675
0
                self.end.replace_zero();
676
0
                Some(self.start.replace_one())
677
            },
678
0
            _ => None
679
        }
680
0
    }
681
0
    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
682
0
        let n = n as u64;
683
0
        let count = self.count_u64();
684
0
        if n >= count {
685
0
            self.end.replace_zero();
686
0
            self.start.replace_one();
687
0
            None
688
0
        } else if n == count - 1 {
689
0
            self.end.replace_zero();
690
0
            Some(self.start.replace_one())
691
        } else {
692
0
            let nth_back = self.end.saturating_sub(n as u32);
693
0
            self.end = nth_back.sub_one();
694
0
            Some(nth_back)
695
        }
696
0
    }
697
}
698
699
impl DoubleEndedIterator for Ipv6AddrRange {
700
0
    fn next_back(&mut self) -> Option<Self::Item> {
701
0
        match self.start.partial_cmp(&self.end) {
702
            Some(Less) => {
703
0
                let next_back = self.end.sub_one();
704
0
                Some(mem::replace(&mut self.end, next_back))
705
            },
706
            Some(Equal) => {
707
0
                self.end.replace_zero();
708
0
                Some(self.start.replace_one())
709
            },
710
0
            _ => None
711
        }
712
0
    }
713
0
    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
714
0
        let n = n as u128;
715
0
        if self.can_count_u128() {
716
0
            let count = self.count_u128();
717
0
            if n >= count {
718
0
                self.end.replace_zero();
719
0
                self.start.replace_one();
720
0
                None
721
            }
722
0
            else if n == count - 1 {
723
0
                self.end.replace_zero();
724
0
                Some(self.start.replace_one())
725
            } else {
726
0
                let nth_back = self.end.saturating_sub(n);
727
0
                self.end = nth_back.sub_one();
728
0
                Some(nth_back)
729
            }
730
        // count overflows u128; n is 64-bits at most.
731
        // therefore, n can never exceed count
732
        } else {
733
0
            let nth_back = self.end.saturating_sub(n);
734
0
            self.end = nth_back.sub_one();
735
0
            Some(nth_back)
736
        }
737
0
    }
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]
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
}