diff options
| author | The8472 <git@infinite-source.de> | 2021-08-02 20:28:31 +0200 |
|---|---|---|
| committer | The8472 <git@infinite-source.de> | 2021-08-02 20:28:31 +0200 |
| commit | a5cdff3bd42e82f58de45dd49d468a6d4c54b54b (patch) | |
| tree | abcb43994f9234e202a3ab27ea7992f1c4b748ec /library/std/src | |
| parent | a985d8e6c7f0519fa1e147854430a381ac4eadf8 (diff) | |
| download | rust-a5cdff3bd42e82f58de45dd49d468a6d4c54b54b.tar.gz rust-a5cdff3bd42e82f58de45dd49d468a6d4c54b54b.zip | |
Add convenience for handling ipv4-mapped addresses by canonicalizing them
This simplifies checking common properties in an address-family-agnostic way since since #86335 commits to not checking IPv4 semantics of IPv4-mapped addresses in the `Ipv6Addr` property methods.
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/net/ip.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 88309875978..2108c62b4cd 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -291,6 +291,29 @@ impl IpAddr { pub const fn is_ipv6(&self) -> bool { matches!(self, IpAddr::V6(_)) } + + /// Converts this address to an `IpAddr::V4` if it is a IPv4-mapped IPv6 addresses, otherwise it + /// return `self` as-is. + /// + /// # Examples + /// + /// ``` + /// #![feature(ip)] + /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; + /// + /// assert_eq!(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)).to_canonical().is_loopback(), true); + /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).is_loopback(), false); + /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1)).to_canonical().is_loopback(), true); + /// ``` + #[inline] + #[rustc_const_unstable(feature = "const_ip", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] + pub const fn to_canonical(&self) -> IpAddr { + match self { + &v4 @ IpAddr::V4(_) => v4, + IpAddr::V6(v6) => v6.to_canonical(), + } + } } impl Ipv4Addr { @@ -1532,6 +1555,28 @@ impl Ipv6Addr { } } + /// Converts this address to an `IpAddr::V4` if it is a IPv4-mapped addresses, otherwise it + /// returns self wrapped in a `IpAddr::V6`. + /// + /// # Examples + /// + /// ``` + /// #![feature(ip)] + /// use std::net::Ipv6Addr; + /// + /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).is_loopback(), false); + /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0x7f00, 0x1).to_canonical().is_loopback(), true); + /// ``` + #[inline] + #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] + pub const fn to_canonical(&self) -> IpAddr { + if let Some(mapped) = self.to_ipv4_mapped() { + return IpAddr::V4(mapped); + } + IpAddr::V6(*self) + } + /// Returns the sixteen eight-bit integers the IPv6 address consists of. /// /// ``` |
