Skip to content

Commit 9cf4674

Browse files
authored
Rollup merge of #87708 - the8472:canonical_v6, r=dtolnay
Add convenience method for handling ipv4-mapped addresses by canonicalizing them This simplifies checking common properties in an address-family-agnostic way since #86335 commits to not checking IPv4 semantics of IPv4-mapped addresses in the `Ipv6Addr` property methods.
2 parents dfcff8a + a5cdff3 commit 9cf4674

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

library/std/src/net/ip.rs

+45
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,29 @@ impl IpAddr {
333333
pub const fn is_ipv6(&self) -> bool {
334334
matches!(self, IpAddr::V6(_))
335335
}
336+
337+
/// Converts this address to an `IpAddr::V4` if it is a IPv4-mapped IPv6 addresses, otherwise it
338+
/// return `self` as-is.
339+
///
340+
/// # Examples
341+
///
342+
/// ```
343+
/// #![feature(ip)]
344+
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
345+
///
346+
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).to_canonical().is_loopback(), true);
347+
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).is_loopback(), false);
348+
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).to_canonical().is_loopback(), true);
349+
/// ```
350+
#[inline]
351+
#[rustc_const_unstable(feature = "const_ip", issue = "76205")]
352+
#[unstable(feature = "ip", issue = "27709")]
353+
pub const fn to_canonical(&self) -> IpAddr {
354+
match self {
355+
&v4 @ IpAddr::V4(_) => v4,
356+
IpAddr::V6(v6) => v6.to_canonical(),
357+
}
358+
}
336359
}
337360

338361
impl Ipv4Addr {
@@ -1540,6 +1563,28 @@ impl Ipv6Addr {
15401563
}
15411564
}
15421565

1566+
/// Converts this address to an `IpAddr::V4` if it is a IPv4-mapped addresses, otherwise it
1567+
/// returns self wrapped in a `IpAddr::V6`.
1568+
///
1569+
/// # Examples
1570+
///
1571+
/// ```
1572+
/// #![feature(ip)]
1573+
/// use std::net::Ipv6Addr;
1574+
///
1575+
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).is_loopback(), false);
1576+
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).to_canonical().is_loopback(), true);
1577+
/// ```
1578+
#[inline]
1579+
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
1580+
#[unstable(feature = "ip", issue = "27709")]
1581+
pub const fn to_canonical(&self) -> IpAddr {
1582+
if let Some(mapped) = self.to_ipv4_mapped() {
1583+
return IpAddr::V4(mapped);
1584+
}
1585+
IpAddr::V6(*self)
1586+
}
1587+
15431588
/// Returns the sixteen eight-bit integers the IPv6 address consists of.
15441589
///
15451590
/// ```

0 commit comments

Comments
 (0)