Rollup merge of #119081 - jstasiak:is-ipv4-mapped, r=dtolnay
Add Ipv6Addr::is_ipv4_mapped This change consists of cherry-picking the content from the original PR[1], which got closed due to inactivity, and applying the following changes: * Resolving merge conflicts (obviously) * Linked to to_ipv4_mapped instead of to_ipv4 in the documentation (seems more appropriate) * Added the must_use and rustc_const_unstable attributes the original didn't have I think it's a reasonably useful method to have. [1] https://github.com/rust-lang/rust/pull/86490
This commit is contained in:
commit
3cd378cc15
@ -1785,6 +1785,31 @@ pub const fn is_multicast(&self) -> bool {
|
||||
(self.segments()[0] & 0xff00) == 0xff00
|
||||
}
|
||||
|
||||
/// Returns [`true`] if the address is an IPv4-mapped address (`::ffff:0:0/96`).
|
||||
///
|
||||
/// IPv4-mapped addresses can be converted to their canonical IPv4 address with
|
||||
/// [`to_ipv4_mapped`](Ipv6Addr::to_ipv4_mapped).
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// #![feature(ip)]
|
||||
///
|
||||
/// use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
///
|
||||
/// let ipv4_mapped = Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped();
|
||||
/// assert_eq!(ipv4_mapped.is_ipv4_mapped(), true);
|
||||
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x2ff).is_ipv4_mapped(), true);
|
||||
///
|
||||
/// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_ipv4_mapped(), false);
|
||||
/// ```
|
||||
#[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
|
||||
#[unstable(feature = "ip", issue = "27709")]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn is_ipv4_mapped(&self) -> bool {
|
||||
matches!(self.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
|
||||
}
|
||||
|
||||
/// Converts this address to an [`IPv4` address] if it's an [IPv4-mapped] address,
|
||||
/// as defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`].
|
||||
///
|
||||
|
@ -516,6 +516,7 @@ macro_rules! check {
|
||||
| multicast_realm_local
|
||||
| multicast_site_local
|
||||
| multicast_organization_local;
|
||||
let ipv4_mapped: u32 = 1 << 17;
|
||||
|
||||
if ($mask & unspecified) == unspecified {
|
||||
assert!(ip!($s).is_unspecified());
|
||||
@ -592,6 +593,11 @@ macro_rules! check {
|
||||
assert_eq!(ip!($s).multicast_scope().unwrap(),
|
||||
Ipv6MulticastScope::Global);
|
||||
}
|
||||
if ($mask & ipv4_mapped) == ipv4_mapped {
|
||||
assert!(ip!($s).is_ipv4_mapped());
|
||||
} else {
|
||||
assert!(!ip!($s).is_ipv4_mapped());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -610,6 +616,7 @@ macro_rules! check {
|
||||
let multicast_site_local: u32 = 1 << 13;
|
||||
let multicast_organization_local: u32 = 1 << 14;
|
||||
let multicast_global: u32 = 1 << 15;
|
||||
let ipv4_mapped: u32 = 1 << 17;
|
||||
|
||||
check!("::", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unspecified);
|
||||
|
||||
@ -622,7 +629,7 @@ macro_rules! check {
|
||||
check!(
|
||||
"::ffff:127.0.0.1",
|
||||
&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x7f, 0, 0, 1],
|
||||
unicast_global
|
||||
unicast_global | ipv4_mapped
|
||||
);
|
||||
|
||||
check!(
|
||||
@ -996,6 +1003,9 @@ fn ipv6_const() {
|
||||
const IS_MULTICAST: bool = IP_ADDRESS.is_multicast();
|
||||
assert!(!IS_MULTICAST);
|
||||
|
||||
const IS_IPV4_MAPPED: bool = IP_ADDRESS.is_ipv4_mapped();
|
||||
assert!(!IS_IPV4_MAPPED);
|
||||
|
||||
const IP_V4: Option<Ipv4Addr> = IP_ADDRESS.to_ipv4();
|
||||
assert_eq!(IP_V4.unwrap(), Ipv4Addr::new(0, 0, 0, 1));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user