From 30710c3ec4325b9f3c3e0ebdd832fd9f0450fbbd Mon Sep 17 00:00:00 2001
From: ltdk <usr@ltdk.xyz>
Date: Sat, 15 Jul 2023 23:03:44 -0400
Subject: [PATCH 1/2] Add BITS, from_bits, to_bits to IP addresses

---
 library/core/src/lib.rs         |   1 +
 library/core/src/net/ip_addr.rs | 166 ++++++++++++++++++++++----------
 2 files changed, 115 insertions(+), 52 deletions(-)

diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 05876f5fc58..9510e9efcdc 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -165,6 +165,7 @@
 #![feature(duration_consts_float)]
 #![feature(internal_impls_macro)]
 #![feature(ip)]
+#![feature(ip_bits)]
 #![feature(is_ascii_octdigit)]
 #![feature(maybe_uninit_uninit_array)]
 #![feature(ptr_alignment_type)]
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index c51913fa8ab..d3f9834dc95 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -450,6 +450,57 @@ impl Ipv4Addr {
         Ipv4Addr { octets: [a, b, c, d] }
     }
 
+    /// The size of an IPv4 address in bits.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip_bits)]
+    /// use std::net::Ipv4Addr;
+    ///
+    /// assert_eq!(Ipv4Addr::BITS, 32);
+    /// ```
+    #[unstable(feature = "ip_bits", issue = "113744")]
+    pub const BITS: u32 = 32;
+
+    /// Converts an IPv4 address into host byte order `u32`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip_bits)]
+    /// use std::net::Ipv4Addr;
+    ///
+    /// let addr = Ipv4Addr::new(0x12, 0x34, 0x56, 0x78);
+    /// assert_eq!(0x12345678, addr.to_bits());
+    /// ```
+    #[rustc_const_unstable(feature = "ip_bits", issue = "113744")]
+    #[unstable(feature = "ip_bits", issue = "113744")]
+    #[must_use]
+    #[inline]
+    pub const fn to_bits(self) -> u32 {
+        u32::from_be_bytes(self.octets)
+    }
+
+    /// Converts a host byte order `u32` into an IPv4 address.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip_bits)]
+    /// use std::net::Ipv4Addr;
+    ///
+    /// let addr = Ipv4Addr::from(0x12345678);
+    /// assert_eq!(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78), addr);
+    /// ```
+    #[rustc_const_unstable(feature = "ip_bits", issue = "113744")]
+    #[unstable(feature = "ip_bits", issue = "113744")]
+    #[must_use]
+    #[inline]
+    pub const fn from_bits(bits: u32) -> Ipv4Addr {
+        Ipv4Addr { octets: bits.to_be_bytes() }
+    }
+
     /// An IPv4 address with the address pointing to localhost: `127.0.0.1`
     ///
     /// # Examples
@@ -1069,37 +1120,17 @@ impl Ord for Ipv4Addr {
 
 #[stable(feature = "ip_u32", since = "1.1.0")]
 impl From<Ipv4Addr> for u32 {
-    /// Converts an `Ipv4Addr` into a host byte order `u32`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::net::Ipv4Addr;
-    ///
-    /// let addr = Ipv4Addr::new(0x12, 0x34, 0x56, 0x78);
-    /// assert_eq!(0x12345678, u32::from(addr));
-    /// ```
     #[inline]
     fn from(ip: Ipv4Addr) -> u32 {
-        u32::from_be_bytes(ip.octets)
+        ip.to_bits()
     }
 }
 
 #[stable(feature = "ip_u32", since = "1.1.0")]
 impl From<u32> for Ipv4Addr {
-    /// Converts a host byte order `u32` into an `Ipv4Addr`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::net::Ipv4Addr;
-    ///
-    /// let addr = Ipv4Addr::from(0x12345678);
-    /// assert_eq!(Ipv4Addr::new(0x12, 0x34, 0x56, 0x78), addr);
-    /// ```
     #[inline]
     fn from(ip: u32) -> Ipv4Addr {
-        Ipv4Addr { octets: ip.to_be_bytes() }
+        Ipv4Addr::from_bits(ip)
     }
 }
 
@@ -1173,6 +1204,65 @@ impl Ipv6Addr {
         }
     }
 
+    /// The size of an IPv6 address in bits.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip_bits)]
+    /// use std::net::Ipv6Addr;
+    ///
+    /// assert_eq!(Ipv6Addr::BITS, 128);
+    /// ```
+    #[unstable(feature = "ip_bits", issue = "113744")]
+    pub const BITS: u32 = 128;
+
+    /// Converts an IPv6 address into host byte order `u128`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip_bits)]
+    /// use std::net::Ipv6Addr;
+    ///
+    /// let addr = Ipv6Addr::new(
+    ///     0x1020, 0x3040, 0x5060, 0x7080,
+    ///     0x90A0, 0xB0C0, 0xD0E0, 0xF00D,
+    /// );
+    /// assert_eq!(0x102030405060708090A0B0C0D0E0F00D_u128, u128::from(addr));
+    /// ```
+    #[rustc_const_unstable(feature = "ip_bits", issue = "113744")]
+    #[unstable(feature = "ip_bits", issue = "113744")]
+    #[must_use]
+    #[inline]
+    pub const fn to_bits(self) -> u128 {
+        u128::from_be_bytes(self.octets)
+    }
+
+    /// Converts a host byte order `u128` into an IPv6 address.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip_bits)]
+    /// use std::net::Ipv6Addr;
+    ///
+    /// let addr = Ipv6Addr::from(0x102030405060708090A0B0C0D0E0F00D_u128);
+    /// assert_eq!(
+    ///     Ipv6Addr::new(
+    ///         0x1020, 0x3040, 0x5060, 0x7080,
+    ///         0x90A0, 0xB0C0, 0xD0E0, 0xF00D,
+    ///     ),
+    ///     addr);
+    /// ```
+    #[rustc_const_unstable(feature = "ip_bits", issue = "113744")]
+    #[unstable(feature = "ip_bits", issue = "113744")]
+    #[must_use]
+    #[inline]
+    pub const fn from_bits(bits: u128) -> Ipv6Addr {
+        Ipv6Addr { octets: bits.to_be_bytes() }
+    }
+
     /// An IPv6 address representing localhost: `::1`.
     ///
     /// This corresponds to constant `IN6ADDR_LOOPBACK_INIT` or `in6addr_loopback` in other
@@ -1905,44 +1995,16 @@ impl Ord for Ipv6Addr {
 
 #[stable(feature = "i128", since = "1.26.0")]
 impl From<Ipv6Addr> for u128 {
-    /// Convert an `Ipv6Addr` into a host byte order `u128`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::net::Ipv6Addr;
-    ///
-    /// let addr = Ipv6Addr::new(
-    ///     0x1020, 0x3040, 0x5060, 0x7080,
-    ///     0x90A0, 0xB0C0, 0xD0E0, 0xF00D,
-    /// );
-    /// assert_eq!(0x102030405060708090A0B0C0D0E0F00D_u128, u128::from(addr));
-    /// ```
     #[inline]
     fn from(ip: Ipv6Addr) -> u128 {
-        u128::from_be_bytes(ip.octets)
+        ip.to_bits()
     }
 }
 #[stable(feature = "i128", since = "1.26.0")]
 impl From<u128> for Ipv6Addr {
-    /// Convert a host byte order `u128` into an `Ipv6Addr`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::net::Ipv6Addr;
-    ///
-    /// let addr = Ipv6Addr::from(0x102030405060708090A0B0C0D0E0F00D_u128);
-    /// assert_eq!(
-    ///     Ipv6Addr::new(
-    ///         0x1020, 0x3040, 0x5060, 0x7080,
-    ///         0x90A0, 0xB0C0, 0xD0E0, 0xF00D,
-    ///     ),
-    ///     addr);
-    /// ```
     #[inline]
     fn from(ip: u128) -> Ipv6Addr {
-        Ipv6Addr::from(ip.to_be_bytes())
+        Ipv6Addr::from_bits(ip)
     }
 }
 

From b307014d488ede48a70b85c5941a47d2c6fa7480 Mon Sep 17 00:00:00 2001
From: ltdk <usr@ltdk.xyz>
Date: Tue, 18 Jul 2023 20:58:35 -0400
Subject: [PATCH 2/2] Link methods in From impls

---
 library/core/src/net/ip_addr.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index d3f9834dc95..56460c75eba 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -1120,6 +1120,7 @@ impl Ord for Ipv4Addr {
 
 #[stable(feature = "ip_u32", since = "1.1.0")]
 impl From<Ipv4Addr> for u32 {
+    /// Uses [`Ipv4Addr::to_bits`] to convert an IPv4 address to a host byte order `u32`.
     #[inline]
     fn from(ip: Ipv4Addr) -> u32 {
         ip.to_bits()
@@ -1128,6 +1129,7 @@ impl From<Ipv4Addr> for u32 {
 
 #[stable(feature = "ip_u32", since = "1.1.0")]
 impl From<u32> for Ipv4Addr {
+    /// Uses [`Ipv4Addr::from_bits`] to convert a host byte order `u32` into an IPv4 address.
     #[inline]
     fn from(ip: u32) -> Ipv4Addr {
         Ipv4Addr::from_bits(ip)
@@ -1995,6 +1997,7 @@ impl Ord for Ipv6Addr {
 
 #[stable(feature = "i128", since = "1.26.0")]
 impl From<Ipv6Addr> for u128 {
+    /// Uses [`Ipv6Addr::to_bits`] to convert an IPv6 address to a host byte order `u128`.
     #[inline]
     fn from(ip: Ipv6Addr) -> u128 {
         ip.to_bits()
@@ -2002,6 +2005,7 @@ impl From<Ipv6Addr> for u128 {
 }
 #[stable(feature = "i128", since = "1.26.0")]
 impl From<u128> for Ipv6Addr {
+    /// Uses [`Ipv6Addr::from_bits`] to convert a host byte order `u128` to an IPv6 address.
     #[inline]
     fn from(ip: u128) -> Ipv6Addr {
         Ipv6Addr::from_bits(ip)