Skip to main content

ipnet/
ipnet.rs

1use alloc::vec::Vec;
2use core::cmp::max;
3use core::cmp::Ordering::{Less, Equal};
4use core::convert::From;
5use core::fmt;
6use core::iter::FusedIterator;
7use core::option::Option::{Some, None};
8#[cfg(not(feature = "std"))]
9use core::error::Error;
10#[cfg(feature = "std")]
11use std::error::Error;
12#[cfg(not(feature = "std"))]
13use core::net::{IpAddr, Ipv4Addr, Ipv6Addr};
14#[cfg(feature = "std")]
15use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
16
17use crate::ipext::{IpAdd, IpSub, IpStep, IpAddrRange, Ipv4AddrRange, Ipv6AddrRange};
18use crate::mask::{ip_mask_to_prefix, ipv4_mask_to_prefix, ipv6_mask_to_prefix};
19
20/// An IP network address, either IPv4 or IPv6.
21///
22/// This enum can contain either an [`Ipv4Net`] or an [`Ipv6Net`]. A
23/// [`From`] implementation is provided to convert these into an
24/// `IpNet`.
25///
26/// # Textual representation
27///
28/// `IpNet` provides a [`FromStr`] implementation for parsing network
29/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
30/// CIDR notation.
31///
32/// [`Ipv4Net`]: struct.Ipv4Net.html
33/// [`Ipv6Net`]: struct.Ipv6Net.html
34/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
35/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
36/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
37///
38/// # Examples
39///
40/// ```
41/// use std::net::IpAddr;
42/// use ipnet::IpNet;
43///
44/// let net: IpNet = "10.1.1.0/24".parse().unwrap();
45/// assert_eq!(Ok(net.network()), "10.1.1.0".parse());
46///
47/// let net: IpNet = "fd00::/32".parse().unwrap();
48/// assert_eq!(Ok(net.network()), "fd00::".parse());
49/// ```
50#[derive(#[automatically_derived]
impl ::core::marker::Copy for IpNet { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for IpNet { }
#[automatically_derived]
impl ::core::clone::Clone for IpNet {
    #[inline]
    fn clone(&self) -> IpNet {
        let _: ::core::clone::AssertParamIsClone<Ipv4Net>;
        let _: ::core::clone::AssertParamIsClone<Ipv6Net>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for IpNet {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Ipv4Net>;
        let _: ::core::cmp::AssertParamIsEq<Ipv6Net>;
    }
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for IpNet { }
#[automatically_derived]
impl ::core::cmp::PartialEq for IpNet {
    #[inline]
    fn eq(&self, other: &IpNet) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (IpNet::V4(__self_0), IpNet::V4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (IpNet::V6(__self_0), IpNet::V6(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for IpNet {
    #[inline]
    fn cmp(&self, other: &IpNet) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
            ::core::cmp::Ordering::Equal =>
                match (self, other) {
                    (IpNet::V4(__self_0), IpNet::V4(__arg1_0)) =>
                        ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    (IpNet::V6(__self_0), IpNet::V6(__arg1_0)) =>
                        ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    _ => unsafe { ::core::intrinsics::unreachable() }
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for IpNet {
    #[inline]
    fn partial_cmp(&self, other: &IpNet)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for IpNet {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            IpNet::V4(__self_0) => ::core::hash::Hash::hash(__self_0, state),
            IpNet::V6(__self_0) => ::core::hash::Hash::hash(__self_0, state),
        }
    }
}Hash)]
51pub enum IpNet {
52    V4(Ipv4Net),
53    V6(Ipv6Net),
54}
55
56/// An IPv4 network address.
57///
58/// See [`IpNet`] for a type encompassing both IPv4 and IPv6 network
59/// addresses.
60///
61/// # Textual representation
62///
63/// `Ipv4Net` provides a [`FromStr`] implementation for parsing network
64/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
65/// CIDR notation.
66///
67/// [`IpNet`]: enum.IpNet.html
68/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
69/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
70///
71/// # Examples
72///
73/// ```
74/// # #[cfg(feature = "std")]
75/// # use std::net::Ipv6Addr;
76/// # #[cfg(not(feature = "std"))]
77/// # use core::net::Ipv6Addr;
78/// use ipnet::Ipv4Net;
79///
80/// let net: Ipv4Net = "10.1.1.0/24".parse().unwrap();
81/// assert_eq!(Ok(net.network()), "10.1.1.0".parse());
82/// ```
83#[derive(#[automatically_derived]
impl ::core::marker::Copy for Ipv4Net { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Ipv4Net { }
#[automatically_derived]
impl ::core::clone::Clone for Ipv4Net {
    #[inline]
    fn clone(&self) -> Ipv4Net {
        let _: ::core::clone::AssertParamIsClone<Ipv4Addr>;
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for Ipv4Net {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Ipv4Addr>;
        let _: ::core::cmp::AssertParamIsEq<u8>;
    }
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for Ipv4Net { }
#[automatically_derived]
impl ::core::cmp::PartialEq for Ipv4Net {
    #[inline]
    fn eq(&self, other: &Ipv4Net) -> bool {
        self.prefix_len == other.prefix_len && self.addr == other.addr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for Ipv4Net {
    #[inline]
    fn cmp(&self, other: &Ipv4Net) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.addr, &other.addr) {
            ::core::cmp::Ordering::Equal =>
                ::core::cmp::Ord::cmp(&self.prefix_len, &other.prefix_len),
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for Ipv4Net {
    #[inline]
    fn partial_cmp(&self, other: &Ipv4Net)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for Ipv4Net {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.addr, state);
        ::core::hash::Hash::hash(&self.prefix_len, state)
    }
}Hash)]
84pub struct Ipv4Net {
85    addr: Ipv4Addr,
86    prefix_len: u8,
87}
88
89/// An IPv6 network address.
90///
91/// See [`IpNet`] for a type encompassing both IPv4 and IPv6 network
92/// addresses.
93///
94/// # Textual representation
95///
96/// `Ipv6Net` provides a [`FromStr`] implementation for parsing network
97/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
98/// CIDR notation.
99///
100/// [`IpNet`]: enum.IpNet.html
101/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
102/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
103///
104/// # Examples
105///
106/// ```
107/// use std::net::Ipv6Addr;
108/// use ipnet::Ipv6Net;
109///
110/// let net: Ipv6Net = "fd00::/32".parse().unwrap();
111/// assert_eq!(Ok(net.network()), "fd00::".parse());
112/// ```
113#[derive(#[automatically_derived]
impl ::core::marker::Copy for Ipv6Net { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Ipv6Net { }
#[automatically_derived]
impl ::core::clone::Clone for Ipv6Net {
    #[inline]
    fn clone(&self) -> Ipv6Net {
        let _: ::core::clone::AssertParamIsClone<Ipv6Addr>;
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for Ipv6Net {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Ipv6Addr>;
        let _: ::core::cmp::AssertParamIsEq<u8>;
    }
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for Ipv6Net { }
#[automatically_derived]
impl ::core::cmp::PartialEq for Ipv6Net {
    #[inline]
    fn eq(&self, other: &Ipv6Net) -> bool {
        self.prefix_len == other.prefix_len && self.addr == other.addr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for Ipv6Net {
    #[inline]
    fn cmp(&self, other: &Ipv6Net) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.addr, &other.addr) {
            ::core::cmp::Ordering::Equal =>
                ::core::cmp::Ord::cmp(&self.prefix_len, &other.prefix_len),
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for Ipv6Net {
    #[inline]
    fn partial_cmp(&self, other: &Ipv6Net)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for Ipv6Net {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.addr, state);
        ::core::hash::Hash::hash(&self.prefix_len, state)
    }
}Hash)]
114pub struct Ipv6Net {
115    addr: Ipv6Addr,
116    prefix_len: u8,
117}
118
119/// An error which can be returned when the prefix length is invalid.
120///
121/// Valid prefix lengths are 0 to 32 for IPv4 and 0 to 128 for IPv6.
122#[derive(#[automatically_derived]
impl ::core::fmt::Debug for PrefixLenError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "PrefixLenError")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for PrefixLenError {
    #[inline]
    fn clone(&self) -> PrefixLenError { PrefixLenError }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for PrefixLenError { }
#[automatically_derived]
impl ::core::cmp::PartialEq for PrefixLenError {
    #[inline]
    fn eq(&self, other: &PrefixLenError) -> bool { true }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for PrefixLenError {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq)]
123pub struct PrefixLenError;
124
125impl fmt::Display for PrefixLenError {
126    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
127        fmt.write_str("invalid IP prefix length")
128    }
129}
130
131impl Error for PrefixLenError {}
132
133impl IpNet {
134    /// Creates a new IP network address from an `IpAddr` and prefix
135    /// length.
136    ///
137    /// # Examples
138    ///
139    /// ```
140    /// use std::net::Ipv6Addr;
141    /// use ipnet::{IpNet, PrefixLenError};
142    ///
143    /// let net = IpNet::new(Ipv6Addr::LOCALHOST.into(), 48);
144    /// assert!(net.is_ok());
145    /// 
146    /// let bad_prefix_len = IpNet::new(Ipv6Addr::LOCALHOST.into(), 129);
147    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
148    /// ```
149    pub fn new(ip: IpAddr, prefix_len: u8) -> Result<IpNet, PrefixLenError> {
150        Ok(match ip {
151            IpAddr::V4(a) => Ipv4Net::new(a, prefix_len)?.into(),
152            IpAddr::V6(a) => Ipv6Net::new(a, prefix_len)?.into(),
153        })
154    }
155
156    /// Creates a new IP network address from an `IpAddr` and prefix
157    /// length. If called from a const context it will verify prefix length
158    /// at compile time. Otherwise it will panic at runtime if prefix length
159    /// is incorrect for a given IpAddr type.
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
165    /// use ipnet::{IpNet};
166    ///
167    /// // This code is verified at compile time:
168    /// const NET: IpNet = IpNet::new_assert(IpAddr::V4(Ipv4Addr::new(10, 1, 1, 0)), 24);
169    /// assert_eq!(NET.prefix_len(), 24);
170    ///
171    /// // This code is verified at runtime:
172    /// let net = IpNet::new_assert(Ipv6Addr::LOCALHOST.into(), 24);
173    /// assert_eq!(net.prefix_len(), 24);
174    ///
175    /// // This code does not compile:
176    /// // const BAD_PREFIX_LEN: IpNet = IpNet::new_assert(IpAddr::V4(Ipv4Addr::new(10, 1, 1, 0)), 33);
177    ///
178    /// // This code panics at runtime:
179    /// // let bad_prefix_len = IpNet::new_assert(Ipv6Addr::LOCALHOST.into(), 129);
180    /// ```
181    pub const fn new_assert(ip: IpAddr, prefix_len: u8) -> IpNet {
182        match ip {
183            IpAddr::V4(a) => IpNet::V4(Ipv4Net::new_assert(a, prefix_len)),
184            IpAddr::V6(a) => IpNet::V6(Ipv6Net::new_assert(a, prefix_len)),
185        }
186    }
187
188    /// Creates a new IP network address from an `IpAddr` and netmask.
189    ///
190    /// # Examples
191    ///
192    /// ```
193    /// use std::net::Ipv6Addr;
194    /// use ipnet::{IpNet, PrefixLenError};
195    ///
196    /// let net = IpNet::with_netmask(Ipv6Addr::LOCALHOST.into(), Ipv6Addr::from(0xffff_ffff_ffff_0000_0000_0000_0000_0000).into());
197    /// assert!(net.is_ok());
198    ///
199    /// let bad_prefix_len = IpNet::with_netmask(Ipv6Addr::LOCALHOST.into(), Ipv6Addr::from(0xffff_ffff_ffff_0000_0001_0000_0000_0000).into());
200    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
201    /// ```
202    pub fn with_netmask(ip: IpAddr, netmask: IpAddr) -> Result<IpNet, PrefixLenError> {
203        let prefix = ip_mask_to_prefix(netmask)?;
204        Self::new(ip, prefix)
205    }
206
207    /// Returns a copy of the network with the address truncated to the
208    /// prefix length.
209    ///
210    /// # Examples
211    ///
212    /// ```
213    /// # use ipnet::IpNet;
214    /// #
215    /// assert_eq!(
216    ///     "192.168.12.34/16".parse::<IpNet>().unwrap().trunc(),
217    ///     "192.168.0.0/16".parse().unwrap()
218    /// );
219    ///
220    /// assert_eq!(
221    ///     "fd00::1:2:3:4/16".parse::<IpNet>().unwrap().trunc(),
222    ///     "fd00::/16".parse().unwrap()
223    /// );
224    /// ```
225    pub fn trunc(&self) -> IpNet {
226        match *self {
227            IpNet::V4(ref a) => IpNet::V4(a.trunc()),
228            IpNet::V6(ref a) => IpNet::V6(a.trunc()),
229        }
230    }
231
232    /// Returns the address.
233    pub fn addr(&self) -> IpAddr {
234        match *self {
235            IpNet::V4(ref a) => IpAddr::V4(a.addr),
236            IpNet::V6(ref a) => IpAddr::V6(a.addr),
237        }
238    }
239
240    /// Returns the prefix length.
241    pub fn prefix_len(&self) -> u8 {
242        match *self {
243            IpNet::V4(ref a) => a.prefix_len(),
244            IpNet::V6(ref a) => a.prefix_len(),
245        }
246    }
247
248    /// Returns the maximum valid prefix length.
249    pub fn max_prefix_len(&self) -> u8 {
250        match *self {
251            IpNet::V4(ref a) => a.max_prefix_len(),
252            IpNet::V6(ref a) => a.max_prefix_len(),
253        }
254    }
255
256    /// Returns the network mask.
257    ///
258    /// # Examples
259    ///
260    /// ```
261    /// # use std::net::IpAddr;
262    /// # use ipnet::IpNet;
263    /// #
264    /// let net: IpNet = "10.1.0.0/20".parse().unwrap();
265    /// assert_eq!(Ok(net.netmask()), "255.255.240.0".parse());
266    ///
267    /// let net: IpNet = "fd00::/24".parse().unwrap();
268    /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
269    /// ```
270    pub fn netmask(&self) -> IpAddr {
271        match *self {
272            IpNet::V4(ref a) => IpAddr::V4(a.netmask()),
273            IpNet::V6(ref a) => IpAddr::V6(a.netmask()),
274        }
275    }
276
277    /// Returns the host mask.
278    ///
279    /// # Examples
280    ///
281    /// ```
282    /// # use std::net::IpAddr;
283    /// # use ipnet::IpNet;
284    /// #
285    /// let net: IpNet = "10.1.0.0/20".parse().unwrap();
286    /// assert_eq!(Ok(net.hostmask()), "0.0.15.255".parse());
287    ///
288    /// let net: IpNet = "fd00::/24".parse().unwrap();
289    /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
290    /// ```
291    pub fn hostmask(&self) -> IpAddr {
292        match *self {
293            IpNet::V4(ref a) => IpAddr::V4(a.hostmask()),
294            IpNet::V6(ref a) => IpAddr::V6(a.hostmask()),
295        }
296    }
297    
298    /// Returns the network address.
299    ///
300    /// # Examples
301    ///
302    /// ```
303    /// # use std::net::IpAddr;
304    /// # use ipnet::IpNet;
305    /// #
306    /// let net: IpNet = "172.16.123.123/16".parse().unwrap();
307    /// assert_eq!(Ok(net.network()), "172.16.0.0".parse());
308    ///
309    /// let net: IpNet = "fd00:1234:5678::/24".parse().unwrap();
310    /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
311    /// ```
312    pub fn network(&self) -> IpAddr {
313        match *self {
314            IpNet::V4(ref a) => IpAddr::V4(a.network()),
315            IpNet::V6(ref a) => IpAddr::V6(a.network()),
316        }
317    }    
318    
319    /// Returns the broadcast address.
320    ///
321    /// # Examples
322    ///
323    /// ```
324    /// # use std::net::IpAddr;
325    /// # use ipnet::IpNet;
326    /// #
327    /// let net: IpNet = "172.16.0.0/22".parse().unwrap();
328    /// assert_eq!(Ok(net.broadcast()), "172.16.3.255".parse());
329    ///
330    /// let net: IpNet = "fd00:1234:5678::/24".parse().unwrap();
331    /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
332    /// ```
333    pub fn broadcast(&self) -> IpAddr {
334        match *self {
335            IpNet::V4(ref a) => IpAddr::V4(a.broadcast()),
336            IpNet::V6(ref a) => IpAddr::V6(a.broadcast()),
337        }
338    }
339    
340    /// Returns the `IpNet` that contains this one.
341    ///
342    /// # Examples
343    ///
344    /// ```
345    /// # use ipnet::IpNet;
346    /// #
347    /// let n1: IpNet = "172.16.1.0/24".parse().unwrap();
348    /// let n2: IpNet = "172.16.0.0/23".parse().unwrap();
349    /// let n3: IpNet = "172.16.0.0/0".parse().unwrap();
350    ///
351    /// assert_eq!(n1.supernet().unwrap(), n2);
352    /// assert_eq!(n3.supernet(), None);
353    ///
354    /// let n1: IpNet = "fd00:ff00::/24".parse().unwrap();
355    /// let n2: IpNet = "fd00:fe00::/23".parse().unwrap();
356    /// let n3: IpNet = "fd00:fe00::/0".parse().unwrap();
357    ///
358    /// assert_eq!(n1.supernet().unwrap(), n2);
359    /// assert_eq!(n3.supernet(), None);
360    /// ```
361    pub fn supernet(&self) -> Option<IpNet> {
362        match *self {
363            IpNet::V4(ref a) => a.supernet().map(IpNet::V4),
364            IpNet::V6(ref a) => a.supernet().map(IpNet::V6),
365        }
366    }
367
368    /// Returns `true` if this network and the given network are 
369    /// children of the same supernet.
370    ///
371    /// # Examples
372    ///
373    /// ```
374    /// # use ipnet::IpNet;
375    /// #
376    /// let n4_1: IpNet = "10.1.0.0/24".parse().unwrap();
377    /// let n4_2: IpNet = "10.1.1.0/24".parse().unwrap();
378    /// let n4_3: IpNet = "10.1.2.0/24".parse().unwrap();
379    /// let n6_1: IpNet = "fd00::/18".parse().unwrap();
380    /// let n6_2: IpNet = "fd00:4000::/18".parse().unwrap();
381    /// let n6_3: IpNet = "fd00:8000::/18".parse().unwrap();
382    ///
383    /// assert!( n4_1.is_sibling(&n4_2));
384    /// assert!(!n4_2.is_sibling(&n4_3));
385    /// assert!( n6_1.is_sibling(&n6_2));
386    /// assert!(!n6_2.is_sibling(&n6_3));
387    /// assert!(!n4_1.is_sibling(&n6_2));
388    /// ```
389    pub fn is_sibling(&self, other: &IpNet) -> bool {
390        match (*self, *other) {
391            (IpNet::V4(ref a), IpNet::V4(ref b)) => a.is_sibling(b),
392            (IpNet::V6(ref a), IpNet::V6(ref b)) => a.is_sibling(b),
393            _ => false,
394        }
395    }
396
397    /// Return an `Iterator` over the host addresses in this network.
398    ///
399    /// # Examples
400    ///
401    /// ```
402    /// # use std::net::IpAddr;
403    /// # use ipnet::IpNet;
404    /// #
405    /// let net: IpNet = "10.0.0.0/30".parse().unwrap();
406    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
407    ///     "10.0.0.1".parse::<IpAddr>().unwrap(),
408    ///     "10.0.0.2".parse().unwrap(),
409    /// ]);
410    ///
411    /// let net: IpNet = "10.0.0.0/31".parse().unwrap();
412    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
413    ///     "10.0.0.0".parse::<IpAddr>().unwrap(),
414    ///     "10.0.0.1".parse().unwrap(),
415    /// ]);
416    ///
417    /// let net: IpNet = "fd00::/126".parse().unwrap();
418    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
419    ///     "fd00::".parse::<IpAddr>().unwrap(),
420    ///     "fd00::1".parse().unwrap(),
421    ///     "fd00::2".parse().unwrap(),
422    ///     "fd00::3".parse().unwrap(),
423    /// ]);
424    /// ```
425    pub fn hosts(&self) -> IpAddrRange {
426        match *self {
427            IpNet::V4(ref a) => IpAddrRange::V4(a.hosts()),
428            IpNet::V6(ref a) => IpAddrRange::V6(a.hosts()),
429        }
430    }
431    
432    /// Returns an `Iterator` over the subnets of this network with the
433    /// given prefix length.
434    ///
435    /// # Examples
436    ///
437    /// ```
438    /// # use ipnet::{IpNet, PrefixLenError};
439    /// #
440    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
441    /// assert_eq!(net.subnets(26).unwrap().collect::<Vec<IpNet>>(), vec![
442    ///     "10.0.0.0/26".parse::<IpNet>().unwrap(),
443    ///     "10.0.0.64/26".parse().unwrap(),
444    ///     "10.0.0.128/26".parse().unwrap(),
445    ///     "10.0.0.192/26".parse().unwrap(),
446    /// ]);
447    ///
448    /// let net: IpNet = "fd00::/16".parse().unwrap();
449    /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<IpNet>>(), vec![
450    ///     "fd00::/18".parse::<IpNet>().unwrap(),
451    ///     "fd00:4000::/18".parse().unwrap(),
452    ///     "fd00:8000::/18".parse().unwrap(),
453    ///     "fd00:c000::/18".parse().unwrap(),
454    /// ]);
455    ///
456    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
457    /// assert_eq!(net.subnets(23), Err(PrefixLenError));
458    ///
459    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
460    /// assert_eq!(net.subnets(33), Err(PrefixLenError));
461    ///
462    /// let net: IpNet = "fd00::/16".parse().unwrap();
463    /// assert_eq!(net.subnets(15), Err(PrefixLenError));
464    ///
465    /// let net: IpNet = "fd00::/16".parse().unwrap();
466    /// assert_eq!(net.subnets(129), Err(PrefixLenError));
467    /// ```
468    pub fn subnets(&self, new_prefix_len: u8) -> Result<IpSubnets, PrefixLenError> {
469        match *self {
470            IpNet::V4(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V4),
471            IpNet::V6(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V6),
472        }
473    }
474
475    /// Test if a network address contains either another network
476    /// address or an IP address.
477    ///
478    /// # Examples
479    ///
480    /// ```
481    /// # use std::net::IpAddr;
482    /// # use ipnet::IpNet;
483    /// #
484    /// let net4: IpNet = "192.168.0.0/24".parse().unwrap();
485    /// let net4_yes: IpNet = "192.168.0.0/25".parse().unwrap();
486    /// let net4_no: IpNet = "192.168.0.0/23".parse().unwrap();
487    /// let ip4_yes: IpAddr = "192.168.0.1".parse().unwrap();
488    /// let ip4_no: IpAddr = "192.168.1.0".parse().unwrap();
489    ///
490    /// assert!(net4.contains(&net4));
491    /// assert!(net4.contains(&net4_yes));
492    /// assert!(!net4.contains(&net4_no));
493    /// assert!(net4.contains(&ip4_yes));
494    /// assert!(!net4.contains(&ip4_no));
495    ///
496    ///
497    /// let net6: IpNet = "fd00::/16".parse().unwrap();
498    /// let net6_yes: IpNet = "fd00::/17".parse().unwrap();
499    /// let net6_no: IpNet = "fd00::/15".parse().unwrap();
500    /// let ip6_yes: IpAddr = "fd00::1".parse().unwrap();
501    /// let ip6_no: IpAddr = "fd01::".parse().unwrap();
502    ///
503    /// assert!(net6.contains(&net6));
504    /// assert!(net6.contains(&net6_yes));
505    /// assert!(!net6.contains(&net6_no));
506    /// assert!(net6.contains(&ip6_yes));
507    /// assert!(!net6.contains(&ip6_no));
508    ///
509    /// assert!(!net4.contains(&net6));
510    /// assert!(!net6.contains(&net4));
511    /// assert!(!net4.contains(&ip6_no));
512    /// assert!(!net6.contains(&ip4_no));
513    /// ```
514    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
515        Contains::contains(self, other)
516    }
517
518    /// Aggregate a `Vec` of `IpNet`s and return the result as a new
519    /// `Vec`.
520    ///
521    /// # Examples
522    ///
523    /// ```
524    /// # use ipnet::IpNet;
525    /// #
526    /// let nets = vec![
527    ///     "10.0.0.0/24".parse::<IpNet>().unwrap(),
528    ///     "10.0.1.0/24".parse().unwrap(),
529    ///     "10.0.2.0/24".parse().unwrap(),
530    ///     "fd00::/18".parse().unwrap(),
531    ///     "fd00:4000::/18".parse().unwrap(),
532    ///     "fd00:8000::/18".parse().unwrap(),
533    /// ];
534    ///
535    /// assert_eq!(IpNet::aggregate(&nets), vec![
536    ///     "10.0.0.0/23".parse::<IpNet>().unwrap(),
537    ///     "10.0.2.0/24".parse().unwrap(),
538    ///     "fd00::/17".parse().unwrap(),
539    ///     "fd00:8000::/18".parse().unwrap(),
540    /// ]);
541    /// ```
542    pub fn aggregate(networks: &Vec<IpNet>) -> Vec<IpNet> {
543        // It's 2.5x faster to split the input up and run them using the
544        // specific IPv4 and IPV6 implementations. merge_intervals() and
545        // the comparisons are much faster running over integers.
546        let mut ipv4nets: Vec<Ipv4Net> = Vec::new();
547        let mut ipv6nets: Vec<Ipv6Net> = Vec::new();
548
549        for n in networks {
550            match *n {
551                IpNet::V4(x) => ipv4nets.push(x),
552                IpNet::V6(x) => ipv6nets.push(x),
553            }
554        }
555
556        let mut res: Vec<IpNet> = Vec::new();
557        let ipv4aggs = Ipv4Net::aggregate(&ipv4nets);
558        let ipv6aggs = Ipv6Net::aggregate(&ipv6nets);
559        res.extend::<Vec<IpNet>>(ipv4aggs.into_iter().map(IpNet::V4).collect::<Vec<IpNet>>());
560        res.extend::<Vec<IpNet>>(ipv6aggs.into_iter().map(IpNet::V6).collect::<Vec<IpNet>>());
561        res
562    }
563}
564
565impl Default for IpNet {
566    fn default() -> Self {
567        Self::V4(Ipv4Net::default())
568    }
569}
570
571impl fmt::Debug for IpNet {
572    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
573        fmt::Display::fmt(self, fmt)
574    }
575}
576
577impl fmt::Display for IpNet {
578    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
579        match *self {
580            IpNet::V4(ref a) => a.fmt(fmt),
581            IpNet::V6(ref a) => a.fmt(fmt),
582        }
583    }
584}
585
586impl From<Ipv4Net> for IpNet {
587    fn from(net: Ipv4Net) -> IpNet {
588        IpNet::V4(net)
589    }
590}
591
592impl From<Ipv6Net> for IpNet {
593    fn from(net: Ipv6Net) -> IpNet {
594        IpNet::V6(net)
595    }
596}
597
598impl From<IpAddr> for IpNet {
599    fn from(addr: IpAddr) -> IpNet {
600        match addr {
601            IpAddr::V4(a) => IpNet::V4(a.into()),
602            IpAddr::V6(a) => IpNet::V6(a.into()),
603        }
604    }
605}
606
607impl Ipv4Net {
608    /// Creates a new IPv4 network address from an `Ipv4Addr` and prefix
609    /// length.
610    ///
611    /// # Examples
612    ///
613    /// ```
614    /// use std::net::Ipv4Addr;
615    /// use ipnet::{Ipv4Net, PrefixLenError};
616    ///
617    /// let net = Ipv4Net::new(Ipv4Addr::new(10, 1, 1, 0), 24);
618    /// assert!(net.is_ok());
619    ///
620    /// let bad_prefix_len = Ipv4Net::new(Ipv4Addr::new(10, 1, 1, 0), 33);
621    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
622    /// ```
623    #[inline]
624    pub const fn new(ip: Ipv4Addr, prefix_len: u8) -> Result<Ipv4Net, PrefixLenError> {
625        if prefix_len > 32 {
626            return Err(PrefixLenError);
627        }
628        Ok(Ipv4Net { addr: ip, prefix_len: prefix_len })
629    }
630
631    /// Creates a new IPv4 network address from an `Ipv4Addr` and prefix
632    /// length. If called from a const context it will verify prefix length
633    /// at compile time. Otherwise it will panic at runtime if prefix length
634    /// is not less than or equal to 32.
635    ///
636    /// # Examples
637    ///
638    /// ```
639    /// use std::net::Ipv4Addr;
640    /// use ipnet::{Ipv4Net};
641    ///
642    /// // This code is verified at compile time:
643    /// const NET: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 24);
644    /// assert_eq!(NET.prefix_len(), 24);
645    ///
646    /// // This code is verified at runtime:
647    /// let net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 24);
648    /// assert_eq!(NET.prefix_len(), 24);
649    ///
650    /// // This code does not compile:
651    /// // const BAD_PREFIX_LEN: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 33);
652    ///
653    /// // This code panics at runtime:
654    /// // let bad_prefix_len = Ipv4Net::new_assert(Ipv4Addr::new(10, 1, 1, 0), 33);
655    /// ```
656    #[inline]
657    pub const fn new_assert(ip: Ipv4Addr, prefix_len: u8) -> Ipv4Net {
658        if !(prefix_len <= 32) {
    ::core::panicking::panic("prefix_len must be less than or equal to 32 for Ipv4Net")
};assert!(prefix_len <= 32, "prefix_len must be less than or equal to 32 for Ipv4Net");
659        Ipv4Net { addr: ip, prefix_len: prefix_len }
660    }
661
662    /// Creates a new IPv4 network address from an `Ipv4Addr` and netmask.
663    ///
664    /// # Examples
665    ///
666    /// ```
667    /// use std::net::Ipv4Addr;
668    /// use ipnet::{Ipv4Net, PrefixLenError};
669    ///
670    /// let net = Ipv4Net::with_netmask(Ipv4Addr::new(10, 1, 1, 0), Ipv4Addr::new(255, 255, 255, 0));
671    /// assert!(net.is_ok());
672    ///
673    /// let bad_prefix_len = Ipv4Net::with_netmask(Ipv4Addr::new(10, 1, 1, 0), Ipv4Addr::new(255, 255, 0, 1));
674    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
675    /// ```
676    pub fn with_netmask(ip: Ipv4Addr, netmask: Ipv4Addr) -> Result<Ipv4Net, PrefixLenError> {
677        let prefix = ipv4_mask_to_prefix(netmask)?;
678        Self::new(ip, prefix)
679    }
680
681    /// Returns a copy of the network with the address truncated to the
682    /// prefix length.
683    ///
684    /// # Examples
685    ///
686    /// ```
687    /// # use ipnet::Ipv4Net;
688    /// #
689    /// assert_eq!(
690    ///     "192.168.12.34/16".parse::<Ipv4Net>().unwrap().trunc(),
691    ///     "192.168.0.0/16".parse().unwrap()
692    /// );
693    /// ```
694    pub fn trunc(&self) -> Ipv4Net {
695        Ipv4Net::new(self.network(), self.prefix_len).unwrap()
696    }
697
698    /// Returns the address.
699    #[inline]
700    pub const fn addr(&self) -> Ipv4Addr {
701        self.addr
702    }
703
704    /// Returns the prefix length.
705    #[inline]
706    pub const fn prefix_len(&self) -> u8 {
707        self.prefix_len
708    }
709
710    /// Returns the maximum valid prefix length.
711    #[inline]
712    pub const fn max_prefix_len(&self) -> u8 {
713        32
714    }
715    
716    /// Returns the network mask.
717    ///
718    /// # Examples
719    ///
720    /// ```
721    /// # use std::net::Ipv4Addr;
722    /// # use ipnet::Ipv4Net;
723    /// #
724    /// let net: Ipv4Net = "10.1.0.0/20".parse().unwrap();
725    /// assert_eq!(Ok(net.netmask()), "255.255.240.0".parse());
726    /// ```
727    pub fn netmask(&self) -> Ipv4Addr {
728        Ipv4Addr::from(self.netmask_u32())
729    }
730
731    fn netmask_u32(&self) -> u32 {
732        u32::max_value().checked_shl(32 - self.prefix_len as u32).unwrap_or(0)
733    }
734
735    /// Returns the host mask.
736    ///
737    /// # Examples
738    ///
739    /// ```
740    /// # use std::net::Ipv4Addr;
741    /// # use ipnet::Ipv4Net;
742    /// #
743    /// let net: Ipv4Net = "10.1.0.0/20".parse().unwrap();
744    /// assert_eq!(Ok(net.hostmask()), "0.0.15.255".parse());
745    /// ```
746    pub fn hostmask(&self) -> Ipv4Addr {
747        Ipv4Addr::from(self.hostmask_u32())
748    }
749
750    fn hostmask_u32(&self) -> u32 {
751        u32::max_value().checked_shr(self.prefix_len as u32).unwrap_or(0)
752    }
753
754    /// Returns the network address.
755    ///
756    /// # Examples
757    ///
758    /// ```
759    /// # use std::net::Ipv4Addr;
760    /// # use ipnet::Ipv4Net;
761    /// #
762    /// let net: Ipv4Net = "172.16.123.123/16".parse().unwrap();
763    /// assert_eq!(Ok(net.network()), "172.16.0.0".parse());
764    /// ```
765    pub fn network(&self) -> Ipv4Addr {
766        Ipv4Addr::from(u32::from(self.addr) & self.netmask_u32())
767    }
768
769    /// Returns the broadcast address.
770    ///
771    /// # Examples
772    ///
773    /// ```
774    /// # use std::net::Ipv4Addr;
775    /// # use ipnet::Ipv4Net;
776    /// #
777    /// let net: Ipv4Net = "172.16.0.0/22".parse().unwrap();
778    /// assert_eq!(Ok(net.broadcast()), "172.16.3.255".parse());
779    /// ```
780    pub fn broadcast(&self) -> Ipv4Addr {
781        Ipv4Addr::from(u32::from(self.addr) | self.hostmask_u32())
782    }
783
784    /// Returns the `Ipv4Net` that contains this one.
785    ///
786    /// # Examples
787    ///
788    /// ```
789    /// # use ipnet::Ipv4Net;
790    /// #
791    /// let n1: Ipv4Net = "172.16.1.0/24".parse().unwrap();
792    /// let n2: Ipv4Net = "172.16.0.0/23".parse().unwrap();
793    /// let n3: Ipv4Net = "172.16.0.0/0".parse().unwrap();
794    ///
795    /// assert_eq!(n1.supernet().unwrap(), n2);
796    /// assert_eq!(n3.supernet(), None);
797    /// ```
798    pub fn supernet(&self) -> Option<Ipv4Net> {
799        Ipv4Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
800    }
801
802    /// Returns `true` if this network and the given network are 
803    /// children of the same supernet.
804    ///
805    /// # Examples
806    ///
807    /// ```
808    /// # use ipnet::Ipv4Net;
809    /// #
810    /// let n1: Ipv4Net = "10.1.0.0/24".parse().unwrap();
811    /// let n2: Ipv4Net = "10.1.1.0/24".parse().unwrap();
812    /// let n3: Ipv4Net = "10.1.2.0/24".parse().unwrap();
813    ///
814    /// assert!(n1.is_sibling(&n2));
815    /// assert!(!n2.is_sibling(&n3));
816    /// ```
817    pub fn is_sibling(&self, other: &Ipv4Net) -> bool {
818        self.prefix_len > 0 &&
819        self.prefix_len == other.prefix_len &&
820        self.supernet().unwrap().contains(other)
821    }
822    
823    /// Return an `Iterator` over the host addresses in this network.
824    ///
825    /// If the prefix length is less than 31 both the network address
826    /// and broadcast address are excluded. These are only valid host
827    /// addresses when the prefix length is 31.
828    ///
829    /// # Examples
830    ///
831    /// ```
832    /// # use std::net::Ipv4Addr;
833    /// # use ipnet::Ipv4Net;
834    /// #
835    /// let net: Ipv4Net = "10.0.0.0/30".parse().unwrap();
836    /// assert_eq!(net.hosts().collect::<Vec<Ipv4Addr>>(), vec![
837    ///     "10.0.0.1".parse::<Ipv4Addr>().unwrap(),
838    ///     "10.0.0.2".parse().unwrap(),
839    /// ]);
840    ///
841    /// let net: Ipv4Net = "10.0.0.0/31".parse().unwrap();
842    /// assert_eq!(net.hosts().collect::<Vec<Ipv4Addr>>(), vec![
843    ///     "10.0.0.0".parse::<Ipv4Addr>().unwrap(),
844    ///     "10.0.0.1".parse().unwrap(),
845    /// ]);
846    /// ```
847    pub fn hosts(&self) -> Ipv4AddrRange {
848        let mut start = self.network();
849        let mut end = self.broadcast();
850        
851        if self.prefix_len < 31 {
852            start = start.saturating_add(1);
853            end = end.saturating_sub(1);
854        }
855        
856        Ipv4AddrRange::new(start, end)
857    }
858
859    /// Returns an `Iterator` over the subnets of this network with the
860    /// given prefix length.
861    ///
862    /// # Examples
863    ///
864    /// ```
865    /// # use ipnet::{Ipv4Net, PrefixLenError};
866    /// #
867    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
868    /// assert_eq!(net.subnets(26).unwrap().collect::<Vec<Ipv4Net>>(), vec![
869    ///     "10.0.0.0/26".parse::<Ipv4Net>().unwrap(),
870    ///     "10.0.0.64/26".parse().unwrap(),
871    ///     "10.0.0.128/26".parse().unwrap(),
872    ///     "10.0.0.192/26".parse().unwrap(),
873    /// ]);
874    ///
875    /// let net: Ipv4Net = "10.0.0.0/30".parse().unwrap();
876    /// assert_eq!(net.subnets(32).unwrap().collect::<Vec<Ipv4Net>>(), vec![
877    ///     "10.0.0.0/32".parse::<Ipv4Net>().unwrap(),
878    ///     "10.0.0.1/32".parse().unwrap(),
879    ///     "10.0.0.2/32".parse().unwrap(),
880    ///     "10.0.0.3/32".parse().unwrap(),
881    /// ]);
882    ///
883    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
884    /// assert_eq!(net.subnets(23), Err(PrefixLenError));
885    ///
886    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
887    /// assert_eq!(net.subnets(33), Err(PrefixLenError));
888    /// ```
889    pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv4Subnets, PrefixLenError> {
890        if self.prefix_len > new_prefix_len || new_prefix_len > 32 {
891            return Err(PrefixLenError);
892        }
893        
894        Ok(Ipv4Subnets::new(
895            self.network(),
896            self.broadcast(),
897            new_prefix_len,
898        ))
899    }
900
901    /// Test if a network address contains either another network
902    /// address or an IP address.
903    ///
904    /// # Examples
905    ///
906    /// ```
907    /// # use std::net::Ipv4Addr;
908    /// # use ipnet::Ipv4Net;
909    /// #
910    /// let net: Ipv4Net = "192.168.0.0/24".parse().unwrap();
911    /// let net_yes: Ipv4Net = "192.168.0.0/25".parse().unwrap();
912    /// let net_no: Ipv4Net = "192.168.0.0/23".parse().unwrap();
913    /// let ip_yes: Ipv4Addr = "192.168.0.1".parse().unwrap();
914    /// let ip_no: Ipv4Addr = "192.168.1.0".parse().unwrap();
915    ///
916    /// assert!(net.contains(&net));
917    /// assert!(net.contains(&net_yes));
918    /// assert!(!net.contains(&net_no));
919    /// assert!(net.contains(&ip_yes));
920    /// assert!(!net.contains(&ip_no));
921    /// ```
922    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
923        Contains::contains(self, other)
924    }
925
926    /// Aggregate a `Vec` of `Ipv4Net`s and return the result as a new
927    /// `Vec`.
928    ///
929    /// # Examples
930    ///
931    /// ```
932    /// # use ipnet::Ipv4Net;
933    /// #
934    /// let nets = vec![
935    ///     "10.0.0.0/24".parse::<Ipv4Net>().unwrap(),
936    ///     "10.0.1.0/24".parse().unwrap(),
937    ///     "10.0.2.0/24".parse().unwrap(),
938    /// ];
939    ///
940    /// assert_eq!(Ipv4Net::aggregate(&nets), vec![
941    ///     "10.0.0.0/23".parse::<Ipv4Net>().unwrap(),
942    ///     "10.0.2.0/24".parse().unwrap(),
943    /// ]);
944    pub fn aggregate(networks: &Vec<Ipv4Net>) -> Vec<Ipv4Net> {
945        if networks.is_empty() {
946            return Vec::new();
947        }
948
949        let mut intervals: Vec<(u32, u32)> = networks.iter().map(|n| {
950            (u32::from(n.network()), u32::from(n.broadcast()))
951        }).collect();
952
953        intervals.sort_unstable();
954
955        let mut merged: Vec<(u32, u32)> = Vec::with_capacity(intervals.len());
956
957        for (start, end) in intervals {
958            if let Some((_, current_end)) = merged.last_mut() {
959                if start <= current_end.saturating_add(1) {
960                    *current_end = (*current_end).max(end);
961                    continue;
962                }
963            }
964
965            merged.push((start, end));
966        }
967
968        let mut res: Vec<Ipv4Net> = Vec::new();
969        
970        for (start, end) in merged {
971            res.extend(Ipv4Subnets::new(start.into(), end.into(), 0));
972        }
973
974        res
975    }
976}
977
978impl Default for Ipv4Net {
979    fn default() -> Self {
980        Self {
981            addr: Ipv4Addr::from(0),
982            prefix_len: 0,
983        }
984    }
985}
986
987impl fmt::Debug for Ipv4Net {
988    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
989        fmt::Display::fmt(self, fmt)
990    }
991}
992
993impl fmt::Display for Ipv4Net {
994    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
995        fmt.write_fmt(format_args!("{0}/{1}", self.addr, self.prefix_len))write!(fmt, "{}/{}", self.addr, self.prefix_len)
996    }
997}
998
999impl From<Ipv4Addr> for Ipv4Net {
1000    fn from(addr: Ipv4Addr) -> Ipv4Net {
1001        Ipv4Net { addr, prefix_len: 32 }
1002    }
1003}
1004
1005impl Ipv6Net {    
1006    /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
1007    /// length.
1008    ///
1009    /// # Examples
1010    ///
1011    /// ```
1012    /// use std::net::Ipv6Addr;
1013    /// use ipnet::{Ipv6Net, PrefixLenError};
1014    ///
1015    /// let net = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1016    /// assert!(net.is_ok());
1017    ///
1018    /// let bad_prefix_len = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1019    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
1020    /// ```
1021    #[inline]
1022    pub const fn new(ip: Ipv6Addr, prefix_len: u8) -> Result<Ipv6Net, PrefixLenError> {
1023        if prefix_len > 128 {
1024            return Err(PrefixLenError);
1025        }
1026        Ok(Ipv6Net { addr: ip, prefix_len: prefix_len })
1027    }
1028
1029    /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
1030    /// length. If called from a const context it will verify prefix length
1031    /// at compile time. Otherwise it will panic at runtime if prefix length
1032    /// is not less than or equal to 128.
1033    ///
1034    /// # Examples
1035    ///
1036    /// ```
1037    /// use std::net::Ipv6Addr;
1038    /// use ipnet::{Ipv6Net};
1039    ///
1040    /// // This code is verified at compile time:
1041    /// const NET: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1042    /// assert_eq!(NET.prefix_len(), 24);
1043    ///
1044    /// // This code is verified at runtime:
1045    /// let net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
1046    /// assert_eq!(net.prefix_len(), 24);
1047    ///
1048    /// // This code does not compile:
1049    /// // const BAD_PREFIX_LEN: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1050    ///
1051    /// // This code panics at runtime:
1052    /// // let bad_prefix_len = Ipv6Addr::new_assert(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
1053    /// ```
1054    #[inline]
1055    pub const fn new_assert(ip: Ipv6Addr, prefix_len: u8) -> Ipv6Net {
1056        if !(prefix_len <= 128) {
    ::core::panicking::panic("prefix_len must be less than or equal to 128 for Ipv6Net")
};assert!(prefix_len <= 128, "prefix_len must be less than or equal to 128 for Ipv6Net");
1057        Ipv6Net { addr: ip, prefix_len: prefix_len }
1058    }
1059
1060    /// Creates a new IPv6 network address from an `Ipv6Addr` and netmask.
1061    ///
1062    /// # Examples
1063    ///
1064    /// ```
1065    /// use std::net::Ipv6Addr;
1066    /// use ipnet::{Ipv6Net, PrefixLenError};
1067    ///
1068    /// let net = Ipv6Net::with_netmask(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), Ipv6Addr::from(0xffff_ff00_0000_0000_0000_0000_0000_0000));
1069    /// assert!(net.is_ok());
1070    ///
1071    /// let bad_prefix_len = Ipv6Net::with_netmask(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), Ipv6Addr::from(0xffff_ff00_0000_0000_0001_0000_0000_0000));
1072    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
1073    /// ```
1074    pub fn with_netmask(ip: Ipv6Addr, netmask: Ipv6Addr) -> Result<Ipv6Net, PrefixLenError> {
1075        let prefix = ipv6_mask_to_prefix(netmask)?;
1076        Self::new(ip, prefix)
1077    }
1078
1079    /// Returns a copy of the network with the address truncated to the
1080    /// prefix length.
1081    ///
1082    /// # Examples
1083    ///
1084    /// ```
1085    /// # use ipnet::Ipv6Net;
1086    /// #
1087    /// assert_eq!(
1088    ///     "fd00::1:2:3:4/16".parse::<Ipv6Net>().unwrap().trunc(),
1089    ///     "fd00::/16".parse().unwrap()
1090    /// );
1091    /// ```
1092    pub fn trunc(&self) -> Ipv6Net {
1093        Ipv6Net::new(self.network(), self.prefix_len).unwrap()
1094    }
1095    
1096    /// Returns the address.
1097    #[inline]
1098    pub const fn addr(&self) -> Ipv6Addr {
1099        self.addr
1100    }
1101
1102    /// Returns the prefix length.
1103    #[inline]
1104    pub const fn prefix_len(&self) -> u8 {
1105        self.prefix_len
1106    }
1107    
1108    /// Returns the maximum valid prefix length.
1109    #[inline]
1110    pub const fn max_prefix_len(&self) -> u8 {
1111        128
1112    }
1113
1114    /// Returns the network mask.
1115    ///
1116    /// # Examples
1117    ///
1118    /// ```
1119    /// # use std::net::Ipv6Addr;
1120    /// # use ipnet::Ipv6Net;
1121    /// #
1122    /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1123    /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
1124    /// ```
1125    pub fn netmask(&self) -> Ipv6Addr {
1126        self.netmask_u128().into()
1127    }
1128
1129    fn netmask_u128(&self) -> u128 {
1130        u128::max_value().checked_shl((128 - self.prefix_len) as u32).unwrap_or(u128::min_value())
1131    }
1132
1133    /// Returns the host mask.
1134    ///
1135    /// # Examples
1136    ///
1137    /// ```
1138    /// # use std::net::Ipv6Addr;
1139    /// # use ipnet::Ipv6Net;
1140    /// #
1141    /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
1142    /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1143    /// ```
1144    pub fn hostmask(&self) -> Ipv6Addr {
1145        self.hostmask_u128().into()
1146    }
1147
1148    fn hostmask_u128(&self) -> u128 {
1149        u128::max_value().checked_shr(self.prefix_len as u32).unwrap_or(u128::min_value())
1150    }
1151
1152    /// Returns the network address.
1153    ///
1154    /// # Examples
1155    ///
1156    /// ```
1157    /// # use std::net::Ipv6Addr;
1158    /// # use ipnet::Ipv6Net;
1159    /// #
1160    /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1161    /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
1162    /// ```
1163    pub fn network(&self) -> Ipv6Addr {
1164        (u128::from(self.addr) & self.netmask_u128()).into()
1165    }
1166    
1167    /// Returns the last address.
1168    ///
1169    /// Technically there is no such thing as a broadcast address for
1170    /// IPv6. The name is used for consistency with colloquial usage.
1171    ///
1172    /// # Examples
1173    ///
1174    /// ```
1175    /// # use std::net::Ipv6Addr;
1176    /// # use ipnet::Ipv6Net;
1177    /// #
1178    /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
1179    /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
1180    /// ```
1181    pub fn broadcast(&self) -> Ipv6Addr {
1182        (u128::from(self.addr) | self.hostmask_u128()).into()
1183    }
1184
1185    /// Returns the `Ipv6Net` that contains this one.
1186    ///
1187    /// # Examples
1188    ///
1189    /// ```
1190    /// # use std::str::FromStr;
1191    /// # use ipnet::Ipv6Net;
1192    /// #
1193    /// let n1: Ipv6Net = "fd00:ff00::/24".parse().unwrap();
1194    /// let n2: Ipv6Net = "fd00:fe00::/23".parse().unwrap();
1195    /// let n3: Ipv6Net = "fd00:fe00::/0".parse().unwrap();
1196    ///
1197    /// assert_eq!(n1.supernet().unwrap(), n2);
1198    /// assert_eq!(n3.supernet(), None);
1199    /// ```
1200    pub fn supernet(&self) -> Option<Ipv6Net> {
1201        Ipv6Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
1202    }
1203
1204    /// Returns `true` if this network and the given network are 
1205    /// children of the same supernet.
1206    ///
1207    /// # Examples
1208    ///
1209    /// ```
1210    /// # use ipnet::Ipv6Net;
1211    /// #
1212    /// let n1: Ipv6Net = "fd00::/18".parse().unwrap();
1213    /// let n2: Ipv6Net = "fd00:4000::/18".parse().unwrap();
1214    /// let n3: Ipv6Net = "fd00:8000::/18".parse().unwrap();
1215    ///
1216    /// assert!(n1.is_sibling(&n2));
1217    /// assert!(!n2.is_sibling(&n3));
1218    /// ```
1219    pub fn is_sibling(&self, other: &Ipv6Net) -> bool {
1220        self.prefix_len > 0 &&
1221        self.prefix_len == other.prefix_len &&
1222        self.supernet().unwrap().contains(other)
1223    }
1224    
1225    /// Return an `Iterator` over the host addresses in this network.
1226    ///
1227    /// # Examples
1228    ///
1229    /// ```
1230    /// # use std::net::Ipv6Addr;
1231    /// # use ipnet::Ipv6Net;
1232    /// #
1233    /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1234    /// assert_eq!(net.hosts().collect::<Vec<Ipv6Addr>>(), vec![
1235    ///     "fd00::".parse::<Ipv6Addr>().unwrap(),
1236    ///     "fd00::1".parse().unwrap(),
1237    ///     "fd00::2".parse().unwrap(),
1238    ///     "fd00::3".parse().unwrap(),
1239    /// ]);
1240    /// ```
1241    pub fn hosts(&self) -> Ipv6AddrRange {
1242        Ipv6AddrRange::new(self.network(), self.broadcast())
1243    }
1244
1245    /// Returns an `Iterator` over the subnets of this network with the
1246    /// given prefix length.
1247    ///
1248    /// # Examples
1249    ///
1250    /// ```
1251    /// # use ipnet::{Ipv6Net, PrefixLenError};
1252    /// #
1253    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1254    /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1255    ///     "fd00::/18".parse::<Ipv6Net>().unwrap(),
1256    ///     "fd00:4000::/18".parse().unwrap(),
1257    ///     "fd00:8000::/18".parse().unwrap(),
1258    ///     "fd00:c000::/18".parse().unwrap(),
1259    /// ]);
1260    ///
1261    /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
1262    /// assert_eq!(net.subnets(128).unwrap().collect::<Vec<Ipv6Net>>(), vec![
1263    ///     "fd00::/128".parse::<Ipv6Net>().unwrap(),
1264    ///     "fd00::1/128".parse().unwrap(),
1265    ///     "fd00::2/128".parse().unwrap(),
1266    ///     "fd00::3/128".parse().unwrap(),
1267    /// ]);
1268    ///
1269    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1270    /// assert_eq!(net.subnets(15), Err(PrefixLenError));
1271    ///
1272    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1273    /// assert_eq!(net.subnets(129), Err(PrefixLenError));
1274    /// ```
1275    pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv6Subnets, PrefixLenError> {
1276        if self.prefix_len > new_prefix_len || new_prefix_len > 128 {
1277            return Err(PrefixLenError);
1278        }
1279        
1280        Ok(Ipv6Subnets::new(
1281            self.network(),
1282            self.broadcast(),
1283            new_prefix_len,
1284        ))
1285    }
1286
1287    /// Test if a network address contains either another network
1288    /// address or an IP address.
1289    ///
1290    /// # Examples
1291    ///
1292    /// ```
1293    /// # use std::net::Ipv6Addr;
1294    /// # use ipnet::Ipv6Net;
1295    /// #
1296    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
1297    /// let net_yes: Ipv6Net = "fd00::/17".parse().unwrap();
1298    /// let net_no: Ipv6Net = "fd00::/15".parse().unwrap();
1299    /// let ip_yes: Ipv6Addr = "fd00::1".parse().unwrap();
1300    /// let ip_no: Ipv6Addr = "fd01::".parse().unwrap();
1301    ///
1302    /// assert!(net.contains(&net));
1303    /// assert!(net.contains(&net_yes));
1304    /// assert!(!net.contains(&net_no));
1305    /// assert!(net.contains(&ip_yes));
1306    /// assert!(!net.contains(&ip_no));
1307    /// ```
1308    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
1309        Contains::contains(self, other)
1310    }
1311
1312    /// Aggregate a `Vec` of `Ipv6Net`s and return the result as a new
1313    /// `Vec`.
1314    ///
1315    /// # Examples
1316    ///
1317    /// ```
1318    /// # use ipnet::Ipv6Net;
1319    /// #
1320    /// let nets = vec![
1321    ///     "fd00::/18".parse::<Ipv6Net>().unwrap(),
1322    ///     "fd00:4000::/18".parse().unwrap(),
1323    ///     "fd00:8000::/18".parse().unwrap(),
1324    /// ];
1325    /// assert_eq!(Ipv6Net::aggregate(&nets), vec![
1326    ///     "fd00::/17".parse::<Ipv6Net>().unwrap(),
1327    ///     "fd00:8000::/18".parse().unwrap(),
1328    /// ]);
1329    /// ```
1330    pub fn aggregate(networks: &Vec<Ipv6Net>) -> Vec<Ipv6Net> {
1331        if networks.is_empty() {
1332            return Vec::new();
1333        }
1334
1335        let mut intervals: Vec<(u128, u128)> = networks.iter().map(|n| {
1336            (u128::from(n.network()), u128::from(n.broadcast()))
1337        }).collect();
1338
1339        intervals.sort_unstable();
1340
1341        let mut merged: Vec<(u128, u128)> = Vec::with_capacity(intervals.len());
1342
1343        for (start, end) in intervals {
1344            if let Some((_, current_end)) = merged.last_mut() {
1345                if start <= current_end.saturating_add(1) {
1346                    *current_end = (*current_end).max(end);
1347                    continue;
1348                }
1349            }
1350
1351            merged.push((start, end));
1352        }
1353        
1354        let mut res: Vec<Ipv6Net> = Vec::new();
1355        
1356        for (start, end) in merged {
1357            res.extend(Ipv6Subnets::new(start.into(), end.into(), 0));
1358        }
1359
1360        res
1361    }
1362}
1363
1364impl Default for Ipv6Net {
1365    fn default() -> Self {
1366        Self {
1367            addr: Ipv6Addr::from(0),
1368            prefix_len: 0,
1369        }
1370    }
1371}
1372
1373impl fmt::Debug for Ipv6Net {
1374    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1375        fmt::Display::fmt(self, fmt)
1376    }
1377}
1378
1379impl fmt::Display for Ipv6Net {
1380    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1381        fmt.write_fmt(format_args!("{0}/{1}", self.addr, self.prefix_len))write!(fmt, "{}/{}", self.addr, self.prefix_len)
1382    }
1383}
1384
1385impl From<Ipv6Addr> for Ipv6Net {
1386    fn from(addr: Ipv6Addr) -> Ipv6Net {
1387        Ipv6Net { addr, prefix_len: 128 }
1388    }
1389}
1390
1391/// Provides a method to test if a network address contains either
1392/// another network address or an IP address.
1393///
1394/// # Examples
1395///
1396/// ```
1397/// # use std::net::IpAddr;
1398/// # use ipnet::IpNet;
1399/// #
1400/// let n4_1: IpNet = "10.1.1.0/24".parse().unwrap();
1401/// let n4_2: IpNet = "10.1.1.0/26".parse().unwrap();
1402/// let n4_3: IpNet = "10.1.2.0/26".parse().unwrap();
1403/// let ip4_1: IpAddr = "10.1.1.1".parse().unwrap();
1404/// let ip4_2: IpAddr = "10.1.2.1".parse().unwrap();
1405///
1406/// let n6_1: IpNet = "fd00::/16".parse().unwrap();
1407/// let n6_2: IpNet = "fd00::/17".parse().unwrap();
1408/// let n6_3: IpNet = "fd01::/17".parse().unwrap();
1409/// let ip6_1: IpAddr = "fd00::1".parse().unwrap();
1410/// let ip6_2: IpAddr = "fd01::1".parse().unwrap();
1411///
1412/// assert!(n4_1.contains(&n4_2));
1413/// assert!(!n4_1.contains(&n4_3));
1414/// assert!(n4_1.contains(&ip4_1));
1415/// assert!(!n4_1.contains(&ip4_2));
1416///
1417/// assert!(n6_1.contains(&n6_2));
1418/// assert!(!n6_1.contains(&n6_3));
1419/// assert!(n6_1.contains(&ip6_1));
1420/// assert!(!n6_1.contains(&ip6_2));
1421///
1422/// assert!(!n4_1.contains(&n6_1) && !n6_1.contains(&n4_1));
1423/// assert!(!n4_1.contains(&ip6_1) && !n6_1.contains(&ip4_1));
1424/// ```
1425pub trait Contains<T> {
1426    fn contains(&self, other: T) -> bool;
1427}
1428
1429impl<'a> Contains<&'a IpNet> for IpNet {
1430    fn contains(&self, other: &IpNet) -> bool {
1431        match (*self, *other) {
1432            (IpNet::V4(ref a), IpNet::V4(ref b)) => a.contains(b),
1433            (IpNet::V6(ref a), IpNet::V6(ref b)) => a.contains(b),
1434            _ => false,
1435        }
1436    }
1437}
1438
1439impl<'a> Contains<&'a IpAddr> for IpNet {
1440    fn contains(&self, other: &IpAddr) -> bool {
1441        match (*self, *other) {
1442            (IpNet::V4(ref a), IpAddr::V4(ref b)) => a.contains(b),
1443            (IpNet::V6(ref a), IpAddr::V6(ref b)) => a.contains(b),
1444            _ => false,
1445        }
1446    }
1447}
1448
1449impl<'a> Contains<&'a Ipv4Net> for Ipv4Net {
1450    fn contains(&self, other: &'a Ipv4Net) -> bool {
1451        self.network() <= other.network() && other.broadcast() <= self.broadcast()
1452    }
1453}
1454
1455impl<'a> Contains<&'a Ipv4Addr> for Ipv4Net {
1456    fn contains(&self, other: &'a Ipv4Addr) -> bool {
1457        self.network() <= *other && *other <= self.broadcast()
1458    }
1459}
1460
1461impl<'a> Contains<&'a Ipv6Net> for Ipv6Net {
1462    fn contains(&self, other: &'a Ipv6Net) -> bool {
1463        self.network() <= other.network() && other.broadcast() <= self.broadcast()
1464    }
1465}
1466
1467impl<'a> Contains<&'a Ipv6Addr> for Ipv6Net {
1468    fn contains(&self, other: &'a Ipv6Addr) -> bool {
1469        self.network() <= *other && *other <= self.broadcast()
1470    }
1471}
1472
1473/// An `Iterator` that generates IP network addresses, either IPv4 or
1474/// IPv6.
1475///
1476/// Generates the subnets between the provided `start` and `end` IP
1477/// addresses inclusive of `end`. Each iteration generates the next
1478/// network address of the largest valid size it can, while using a
1479/// prefix length not less than `min_prefix_len`.
1480///
1481/// # Examples
1482///
1483/// ```
1484/// # use std::net::{Ipv4Addr, Ipv6Addr};
1485/// # use std::str::FromStr;
1486/// # use ipnet::{IpNet, IpSubnets, Ipv4Subnets, Ipv6Subnets};
1487/// let subnets = IpSubnets::from(Ipv4Subnets::new(
1488///     "10.0.0.0".parse().unwrap(),
1489///     "10.0.0.239".parse().unwrap(),
1490///     26,
1491/// ));
1492/// 
1493/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1494///     "10.0.0.0/26".parse().unwrap(),
1495///     "10.0.0.64/26".parse().unwrap(),
1496///     "10.0.0.128/26".parse().unwrap(),
1497///     "10.0.0.192/27".parse().unwrap(),
1498///     "10.0.0.224/28".parse().unwrap(),
1499/// ]);
1500///
1501/// let subnets = IpSubnets::from(Ipv6Subnets::new(
1502///     "fd00::".parse().unwrap(),
1503///     "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1504///     26,
1505/// ));
1506/// 
1507/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
1508///     "fd00::/26".parse().unwrap(),
1509///     "fd00:40::/26".parse().unwrap(),
1510///     "fd00:80::/26".parse().unwrap(),
1511///     "fd00:c0::/27".parse().unwrap(),
1512///     "fd00:e0::/28".parse().unwrap(),
1513/// ]);
1514/// ```
1515#[derive(#[automatically_derived]
impl ::core::marker::Copy for IpSubnets { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for IpSubnets { }
#[automatically_derived]
impl ::core::clone::Clone for IpSubnets {
    #[inline]
    fn clone(&self) -> IpSubnets {
        let _: ::core::clone::AssertParamIsClone<Ipv4Subnets>;
        let _: ::core::clone::AssertParamIsClone<Ipv6Subnets>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for IpSubnets {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Ipv4Subnets>;
        let _: ::core::cmp::AssertParamIsEq<Ipv6Subnets>;
    }
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for IpSubnets { }
#[automatically_derived]
impl ::core::cmp::PartialEq for IpSubnets {
    #[inline]
    fn eq(&self, other: &IpSubnets) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (IpSubnets::V4(__self_0), IpSubnets::V4(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (IpSubnets::V6(__self_0), IpSubnets::V6(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for IpSubnets {
    #[inline]
    fn cmp(&self, other: &IpSubnets) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
            ::core::cmp::Ordering::Equal =>
                match (self, other) {
                    (IpSubnets::V4(__self_0), IpSubnets::V4(__arg1_0)) =>
                        ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    (IpSubnets::V6(__self_0), IpSubnets::V6(__arg1_0)) =>
                        ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    _ => unsafe { ::core::intrinsics::unreachable() }
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for IpSubnets {
    #[inline]
    fn partial_cmp(&self, other: &IpSubnets)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for IpSubnets {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            IpSubnets::V4(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            IpSubnets::V6(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for IpSubnets {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            IpSubnets::V4(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "V4",
                    &__self_0),
            IpSubnets::V6(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "V6",
                    &__self_0),
        }
    }
}Debug)]
1516pub enum IpSubnets {
1517    V4(Ipv4Subnets),
1518    V6(Ipv6Subnets),
1519}
1520
1521/// An `Iterator` that generates IPv4 network addresses.
1522///
1523/// Generates the subnets between the provided `start` and `end` IP
1524/// addresses inclusive of `end`. Each iteration generates the next
1525/// network address of the largest valid size it can, while using a
1526/// prefix length not less than `min_prefix_len`.
1527///
1528/// # Examples
1529///
1530/// ```
1531/// # use std::net::Ipv4Addr;
1532/// # use std::str::FromStr;
1533/// # use ipnet::{Ipv4Net, Ipv4Subnets};
1534/// let subnets = Ipv4Subnets::new(
1535///     "10.0.0.0".parse().unwrap(),
1536///     "10.0.0.239".parse().unwrap(),
1537///     26,
1538/// );
1539/// 
1540/// assert_eq!(subnets.collect::<Vec<Ipv4Net>>(), vec![
1541///     "10.0.0.0/26".parse().unwrap(),
1542///     "10.0.0.64/26".parse().unwrap(),
1543///     "10.0.0.128/26".parse().unwrap(),
1544///     "10.0.0.192/27".parse().unwrap(),
1545///     "10.0.0.224/28".parse().unwrap(),
1546/// ]);
1547/// ```
1548#[derive(#[automatically_derived]
impl ::core::marker::Copy for Ipv4Subnets { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Ipv4Subnets { }
#[automatically_derived]
impl ::core::clone::Clone for Ipv4Subnets {
    #[inline]
    fn clone(&self) -> Ipv4Subnets {
        let _: ::core::clone::AssertParamIsClone<Ipv4Addr>;
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for Ipv4Subnets {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Ipv4Addr>;
        let _: ::core::cmp::AssertParamIsEq<u8>;
    }
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for Ipv4Subnets { }
#[automatically_derived]
impl ::core::cmp::PartialEq for Ipv4Subnets {
    #[inline]
    fn eq(&self, other: &Ipv4Subnets) -> bool {
        self.min_prefix_len == other.min_prefix_len &&
                self.start == other.start && self.end == other.end
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for Ipv4Subnets {
    #[inline]
    fn cmp(&self, other: &Ipv4Subnets) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.start, &other.start) {
            ::core::cmp::Ordering::Equal =>
                match ::core::cmp::Ord::cmp(&self.end, &other.end) {
                    ::core::cmp::Ordering::Equal =>
                        ::core::cmp::Ord::cmp(&self.min_prefix_len,
                            &other.min_prefix_len),
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for Ipv4Subnets {
    #[inline]
    fn partial_cmp(&self, other: &Ipv4Subnets)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for Ipv4Subnets {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.start, state);
        ::core::hash::Hash::hash(&self.end, state);
        ::core::hash::Hash::hash(&self.min_prefix_len, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Ipv4Subnets {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "Ipv4Subnets",
            "start", &self.start, "end", &self.end, "min_prefix_len",
            &&self.min_prefix_len)
    }
}Debug)]
1549pub struct Ipv4Subnets {
1550    start: Ipv4Addr,
1551    end: Ipv4Addr, // end is inclusive
1552    min_prefix_len: u8,
1553}
1554
1555/// An `Iterator` that generates IPv6 network addresses.
1556///
1557/// Generates the subnets between the provided `start` and `end` IP
1558/// addresses inclusive of `end`. Each iteration generates the next
1559/// network address of the largest valid size it can, while using a
1560/// prefix length not less than `min_prefix_len`.
1561///
1562/// # Examples
1563///
1564/// ```
1565/// # use std::net::Ipv6Addr;
1566/// # use std::str::FromStr;
1567/// # use ipnet::{Ipv6Net, Ipv6Subnets};
1568/// let subnets = Ipv6Subnets::new(
1569///     "fd00::".parse().unwrap(),
1570///     "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
1571///     26,
1572/// );
1573/// 
1574/// assert_eq!(subnets.collect::<Vec<Ipv6Net>>(), vec![
1575///     "fd00::/26".parse().unwrap(),
1576///     "fd00:40::/26".parse().unwrap(),
1577///     "fd00:80::/26".parse().unwrap(),
1578///     "fd00:c0::/27".parse().unwrap(),
1579///     "fd00:e0::/28".parse().unwrap(),
1580/// ]);
1581/// ```
1582#[derive(#[automatically_derived]
impl ::core::marker::Copy for Ipv6Subnets { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Ipv6Subnets { }
#[automatically_derived]
impl ::core::clone::Clone for Ipv6Subnets {
    #[inline]
    fn clone(&self) -> Ipv6Subnets {
        let _: ::core::clone::AssertParamIsClone<Ipv6Addr>;
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::Eq for Ipv6Subnets {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Ipv6Addr>;
        let _: ::core::cmp::AssertParamIsEq<u8>;
    }
}Eq, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for Ipv6Subnets { }
#[automatically_derived]
impl ::core::cmp::PartialEq for Ipv6Subnets {
    #[inline]
    fn eq(&self, other: &Ipv6Subnets) -> bool {
        self.min_prefix_len == other.min_prefix_len &&
                self.start == other.start && self.end == other.end
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Ord for Ipv6Subnets {
    #[inline]
    fn cmp(&self, other: &Ipv6Subnets) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.start, &other.start) {
            ::core::cmp::Ordering::Equal =>
                match ::core::cmp::Ord::cmp(&self.end, &other.end) {
                    ::core::cmp::Ordering::Equal =>
                        ::core::cmp::Ord::cmp(&self.min_prefix_len,
                            &other.min_prefix_len),
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for Ipv6Subnets {
    #[inline]
    fn partial_cmp(&self, other: &Ipv6Subnets)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::hash::Hash for Ipv6Subnets {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.start, state);
        ::core::hash::Hash::hash(&self.end, state);
        ::core::hash::Hash::hash(&self.min_prefix_len, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Ipv6Subnets {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "Ipv6Subnets",
            "start", &self.start, "end", &self.end, "min_prefix_len",
            &&self.min_prefix_len)
    }
}Debug)]
1583pub struct Ipv6Subnets {
1584    start: Ipv6Addr,
1585    end: Ipv6Addr, // end is inclusive
1586    min_prefix_len: u8,
1587}
1588
1589impl Ipv4Subnets {
1590    pub fn new(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Self {
1591        Ipv4Subnets {
1592            start: start,
1593            end: end,
1594            min_prefix_len: min_prefix_len,
1595        }
1596    }
1597}
1598
1599impl Ipv6Subnets {
1600    pub fn new(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Self {
1601        Ipv6Subnets {
1602            start: start,
1603            end: end,
1604            min_prefix_len: min_prefix_len,
1605        }
1606    }
1607}
1608
1609impl From<Ipv4Subnets> for IpSubnets {
1610    fn from(i: Ipv4Subnets) -> IpSubnets {
1611        IpSubnets::V4(i)
1612    }
1613}
1614
1615impl From<Ipv6Subnets> for IpSubnets {
1616    fn from(i: Ipv6Subnets) -> IpSubnets {
1617        IpSubnets::V6(i)
1618    }
1619}
1620
1621impl Iterator for IpSubnets {
1622    type Item = IpNet;
1623
1624    fn next(&mut self) -> Option<Self::Item> {
1625        match *self {
1626            IpSubnets::V4(ref mut a) => a.next().map(IpNet::V4),
1627            IpSubnets::V6(ref mut a) => a.next().map(IpNet::V6),
1628        }
1629    }
1630}
1631
1632fn next_ipv4_subnet(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Ipv4Net {
1633    let range = u32::from(end) - u32::from(start);
1634    let range_lz = range.leading_zeros();
1635    let range_pl = if range_lz + range.trailing_ones() == u32::BITS { range_lz } else { range_lz + 1 };
1636    let start_pl = 32 - u32::from(start).trailing_zeros();
1637    let new_prefix_len = max(max(range_pl as u8, start_pl as u8), min_prefix_len);
1638    Ipv4Net::new(start, new_prefix_len).unwrap()
1639}
1640
1641fn next_ipv6_subnet(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Ipv6Net {
1642    let range = u128::from(end) - u128::from(start);
1643    let range_lz = range.leading_zeros();
1644    let range_pl = if range_lz + range.trailing_ones() == u128::BITS { range_lz } else { range_lz + 1 };
1645    let start_pl = 128 - u128::from(start).trailing_zeros();
1646    let new_prefix_len = max(max(range_pl as u8, start_pl as u8), min_prefix_len);
1647    Ipv6Net::new(start, new_prefix_len).unwrap()
1648}
1649
1650impl Iterator for Ipv4Subnets {
1651    type Item = Ipv4Net;
1652
1653    fn next(&mut self) -> Option<Self::Item> {
1654        match self.start.partial_cmp(&self.end) {
1655            Some(Less) => {
1656                let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1657                self.start = next.broadcast().saturating_add(1);
1658
1659                // Stop the iterator if we saturated self.start.
1660                if self.start == next.broadcast() {
1661                    self.end.replace_zero();
1662                }
1663                Some(next)
1664            },
1665            Some(Equal) => {
1666                let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
1667                self.start = next.broadcast().saturating_add(1);
1668                self.end.replace_zero();
1669                Some(next)
1670            },
1671            _ => None,
1672        }
1673    }
1674}
1675
1676impl Iterator for Ipv6Subnets {
1677    type Item = Ipv6Net;
1678
1679    fn next(&mut self) -> Option<Self::Item> {
1680        match self.start.partial_cmp(&self.end) {
1681            Some(Less) => {
1682                let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1683                self.start = next.broadcast().saturating_add(1);
1684
1685                // Stop the iterator if we saturated self.start.
1686                if self.start == next.broadcast() {
1687                    self.end.replace_zero();
1688                }
1689                Some(next)
1690            },
1691            Some(Equal) => {
1692                let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
1693                self.start = next.broadcast().saturating_add(1);
1694                self.end.replace_zero();
1695                Some(next)
1696            },
1697            _ => None,
1698        }
1699    }
1700}
1701
1702impl FusedIterator for IpSubnets {}
1703impl FusedIterator for Ipv4Subnets {}
1704impl FusedIterator for Ipv6Subnets {}
1705
1706#[cfg(test)]
1707mod tests {
1708    use super::*;
1709
1710    macro_rules! make_ipnet_vec {
1711        ($($x:expr),*) => ( vec![$($x.parse::<IpNet>().unwrap(),)*] );
1712        ($($x:expr,)*) => ( make_ipnet_vec![$($x),*] );
1713    }
1714
1715    #[test]
1716    fn test_make_ipnet_vec() {
1717        assert_eq!(
1718            make_ipnet_vec![
1719                "10.1.1.1/32", "10.2.2.2/24", "10.3.3.3/16",
1720                "fd00::1/128", "fd00::2/127", "fd00::3/126",
1721            ],
1722            vec![
1723                "10.1.1.1/32".parse().unwrap(),
1724                "10.2.2.2/24".parse().unwrap(),
1725                "10.3.3.3/16".parse().unwrap(),
1726                "fd00::1/128".parse().unwrap(),
1727                "fd00::2/127".parse().unwrap(),
1728                "fd00::3/126".parse().unwrap(),
1729            ]
1730        );
1731    }
1732
1733    macro_rules! make_ipv4_subnets_test {
1734        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1735            #[test]
1736            fn $name() {
1737                let subnets = IpSubnets::from(Ipv4Subnets::new(
1738                    $start.parse().unwrap(),
1739                    $end.parse().unwrap(),
1740                    $min_prefix_len,
1741                ));
1742                let results = make_ipnet_vec![$($x),*];
1743                assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1744            }
1745        );
1746        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1747            make_ipv4_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1748        );
1749    }
1750
1751    macro_rules! make_ipv6_subnets_test {
1752        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
1753            #[test]
1754            fn $name() {
1755                let subnets = IpSubnets::from(Ipv6Subnets::new(
1756                    $start.parse().unwrap(),
1757                    $end.parse().unwrap(),
1758                    $min_prefix_len,
1759                ));
1760                let results = make_ipnet_vec![$($x),*];
1761                assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
1762            }
1763        );
1764        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
1765            make_ipv6_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
1766        );
1767    }
1768
1769    make_ipv4_subnets_test!(
1770        test_ipv4_subnets_zero_zero,
1771        "0.0.0.0", "0.0.0.0", 0,
1772        "0.0.0.0/32",
1773    );
1774
1775    make_ipv4_subnets_test!(
1776        test_ipv4_subnets_zero_max,
1777        "0.0.0.0", "255.255.255.255", 0,
1778        "0.0.0.0/0",
1779    );
1780
1781    make_ipv4_subnets_test!(
1782        test_ipv4_subnets_max_max,
1783        "255.255.255.255", "255.255.255.255", 0,
1784        "255.255.255.255/32",
1785    );
1786    
1787    make_ipv4_subnets_test!(
1788        test_ipv4_subnets_none,
1789        "0.0.0.1", "0.0.0.0", 0,
1790    );
1791    
1792    make_ipv4_subnets_test!(
1793        test_ipv4_subnets_one,
1794        "0.0.0.0", "0.0.0.1", 0,
1795        "0.0.0.0/31",
1796    );
1797
1798    make_ipv4_subnets_test!(
1799        test_ipv4_subnets_two,
1800        "0.0.0.0", "0.0.0.2", 0,
1801        "0.0.0.0/31",
1802        "0.0.0.2/32",
1803    );
1804    
1805    make_ipv4_subnets_test!(
1806        test_ipv4_subnets_taper,
1807        "0.0.0.0", "0.0.0.10", 30,
1808        "0.0.0.0/30",
1809        "0.0.0.4/30",
1810        "0.0.0.8/31",
1811        "0.0.0.10/32",
1812    );
1813    
1814    make_ipv6_subnets_test!(
1815        test_ipv6_subnets_zero_zero,
1816        "::", "::", 0,
1817        "::/128",
1818    );
1819
1820    make_ipv6_subnets_test!(
1821        test_ipv6_subnets_zero_max,
1822        "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1823        "::/0",
1824    );
1825
1826    make_ipv6_subnets_test!(
1827        test_ipv6_subnets_max_max,
1828        "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
1829        "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128",
1830    );
1831    
1832    make_ipv6_subnets_test!(
1833        test_ipv6_subnets_none,
1834        "::1", "::", 0,
1835    );
1836    
1837    make_ipv6_subnets_test!(
1838        test_ipv6_subnets_one,
1839        "::", "::1", 0,
1840        "::/127",
1841    );
1842
1843    make_ipv6_subnets_test!(
1844        test_ipv6_subnets_two,
1845        "::", "::2", 0,
1846        "::/127",
1847        "::2/128",
1848    );
1849
1850    make_ipv6_subnets_test!(
1851        test_ipv6_subnets_taper,
1852        "::", "::a", 126,
1853        "::/126",
1854        "::4/126",
1855        "::8/127",
1856        "::a/128",
1857    );
1858
1859    // Issue #70
1860    #[test]
1861    fn test_ipv4_subnets_zero_max_minus_one() {
1862        let subnets: Vec<Ipv4Net> = Ipv4Subnets::new(Ipv4Addr::from(0u32), Ipv4Addr::from(u32::MAX-1), 0).collect();
1863        assert!(!subnets[0].contains(&Ipv4Addr::from(u32::MAX)));
1864    }
1865    
1866    // Issue #70
1867    #[test]
1868    fn test_ipv6_subnets_zero_max_minus_one() {
1869        let subnets: Vec<Ipv6Net> = Ipv6Subnets::new(Ipv6Addr::from(0u128), Ipv6Addr::from(u128::MAX-1), 0).collect();
1870        assert!(!subnets[0].contains(&Ipv6Addr::from(u128::MAX)));
1871    }
1872
1873    #[test]
1874    fn ipnet_aggregate() {
1875        let ip_nets = make_ipnet_vec![
1876            "10.0.0.0/24", "10.0.1.0/24", "10.0.1.1/24", "10.0.1.2/24",
1877            "10.0.2.0/24",
1878            "10.1.0.0/24", "10.1.1.0/24",
1879            "192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24", "192.168.3.0/24",
1880            "fd00::/32", "fd00:1::/32",
1881            "fd00:2::/32",
1882        ];
1883
1884        let ip_aggs = make_ipnet_vec![
1885            "10.0.0.0/23",
1886            "10.0.2.0/24",
1887            "10.1.0.0/23",
1888            "192.168.0.0/22",
1889            "fd00::/31",
1890            "fd00:2::/32",
1891        ];
1892        
1893        assert_eq!(IpNet::aggregate(&ip_nets), ip_aggs);
1894        
1895        // Issue #44
1896        assert_eq!(IpNet::aggregate(&make_ipnet_vec!["128.0.0.0/1"]), make_ipnet_vec!["128.0.0.0/1"]);
1897        assert_eq!(IpNet::aggregate(&make_ipnet_vec!["0.0.0.0/1", "128.0.0.0/1"]), make_ipnet_vec!["0.0.0.0/0"]);
1898        assert_eq!(IpNet::aggregate(&make_ipnet_vec!["8000::/1"]), make_ipnet_vec!["8000::/1"]);
1899        assert_eq!(IpNet::aggregate(&make_ipnet_vec!["::/1", "8000::/1"]), make_ipnet_vec!["::/0"]);
1900        
1901        // Issue #71
1902        assert_eq!(IpNet::aggregate(&make_ipnet_vec!["255.255.255.254/32"]), make_ipnet_vec!["255.255.255.254/32"]);
1903        assert_eq!(IpNet::aggregate(&make_ipnet_vec!["255.255.255.255/32"]), make_ipnet_vec!["255.255.255.255/32"]);
1904        assert_eq!(IpNet::aggregate(&make_ipnet_vec!["255.255.255.252/31", "255.255.255.254/32"]), make_ipnet_vec!["255.255.255.252/31", "255.255.255.254/32"]);
1905        assert_eq!(IpNet::aggregate(&make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/128"]), make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/128"]);
1906        assert_eq!(IpNet::aggregate(&make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"]), make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"]);
1907        assert_eq!(IpNet::aggregate(&make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc/127", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/128"]), make_ipnet_vec!["ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc/127", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/128"]);
1908    }
1909
1910    #[test]
1911    fn ipnet_default() {
1912        let ipnet: IpNet = "0.0.0.0/0".parse().unwrap();
1913        assert_eq!(ipnet, IpNet::default());
1914    }
1915
1916    #[test]
1917    fn ipv4net_default() {
1918        let ipnet: Ipv4Net = "0.0.0.0/0".parse().unwrap();
1919        assert_eq!(ipnet, Ipv4Net::default());
1920    }
1921
1922    #[test]
1923    fn ipv6net_default() {
1924        let ipnet: Ipv6Net = "::/0".parse().unwrap();
1925        assert_eq!(ipnet, Ipv6Net::default());
1926    }
1927
1928    #[test]
1929    fn new_assert() {
1930        const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1931        const _: Ipv4Net = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1932        const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1933        const _: Ipv6Net = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1934
1935        let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 0);
1936        let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 32);
1937        let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 0);
1938        let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 128);
1939    }
1940
1941    #[test]
1942    #[should_panic]
1943    fn ipv4net_new_assert_panics() {
1944        let _ = Ipv4Net::new_assert(Ipv4Addr::new(0, 0, 0, 0), 33);
1945    }
1946
1947    #[test]
1948    #[should_panic]
1949    fn ipv6net_new_assert_panics() {
1950        let _ = Ipv6Net::new_assert(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), 129);
1951    }
1952}