about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2025-02-21 19:01:13 +0100
committerGitHub <noreply@github.com>2025-02-21 19:01:13 +0100
commit4aa973b3e43a810cc0f37a182da22feb80d73e81 (patch)
treea2dd1dd13263e79fbd4c5c4b2b9466c6c7a407da
parent28164f1229e02856070e61644c0f44ea39658fba (diff)
parent8fb888555fb54dfd39529bca6f1180c083bfe36f (diff)
downloadrust-4aa973b3e43a810cc0f37a182da22feb80d73e81.tar.gz
rust-4aa973b3e43a810cc0f37a182da22feb80d73e81.zip
Rollup merge of #136609 - mammothbane:master, r=scottmcm
libcore/net: `IpAddr::as_octets()`

[ACP](https://github.com/rust-lang/libs-team/issues/535)
[Tracking issue](https://github.com/rust-lang/rust/issues/137259)

Adds `const` `core::net::IpAddr{,v4,v6}::as_octets()` methods to provide reference access to IP address contents.

The concrete usecase for me is allowing the `IpAddr` to provide an extended lifetime in contexts that want a `&[u8]`:

```rust
trait AddrSlice {
    fn addr_slice(&self) -> &[u8];
}

impl AddrSlice for IpAddrV4 {
    fn addr_slice(&self) -> &[u8] {
        // self.octets() doesn't help us here, because we can't return a reference to the owned array.
        // Instead we want the IpAddrV4 to continue owning the memory:
        self.as_octets()
    }
}
```

(Notably, in this case we can't parameterize `AddrSlice` by a `const N: usize` (such that `fn addr_slice(&self) -> [u8; N]`) and maintain object-safety.)
-rw-r--r--library/core/src/net/ip_addr.rs60
1 files changed, 60 insertions, 0 deletions
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index b11ba056853..8e4417ec461 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -451,6 +451,28 @@ impl IpAddr {
             IpAddr::V6(v6) => v6.to_canonical(),
         }
     }
+
+    /// Returns the eight-bit integers this address consists of as a slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip_as_octets)]
+    ///
+    /// use std::net::{Ipv4Addr, Ipv6Addr, IpAddr};
+    ///
+    /// assert_eq!(IpAddr::V4(Ipv4Addr::LOCALHOST).as_octets(), &[127, 0, 0, 1]);
+    /// assert_eq!(IpAddr::V6(Ipv6Addr::LOCALHOST).as_octets(),
+    ///            &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
+    /// ```
+    #[unstable(feature = "ip_as_octets", issue = "137259")]
+    #[inline]
+    pub const fn as_octets(&self) -> &[u8] {
+        match self {
+            IpAddr::V4(ip) => ip.as_octets().as_slice(),
+            IpAddr::V6(ip) => ip.as_octets().as_slice(),
+        }
+    }
 }
 
 impl Ipv4Addr {
@@ -616,6 +638,25 @@ impl Ipv4Addr {
         Ipv4Addr { octets }
     }
 
+    /// Returns the four eight-bit integers that make up this address
+    /// as a slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip_as_octets)]
+    ///
+    /// use std::net::Ipv4Addr;
+    ///
+    /// let addr = Ipv4Addr::new(127, 0, 0, 1);
+    /// assert_eq!(addr.as_octets(), &[127, 0, 0, 1]);
+    /// ```
+    #[unstable(feature = "ip_as_octets", issue = "137259")]
+    #[inline]
+    pub const fn as_octets(&self) -> &[u8; 4] {
+        &self.octets
+    }
+
     /// Returns [`true`] for the special 'unspecified' address (`0.0.0.0`).
     ///
     /// This property is defined in _UNIX Network Programming, Second Edition_,
@@ -2001,6 +2042,25 @@ impl Ipv6Addr {
     pub const fn from_octets(octets: [u8; 16]) -> Ipv6Addr {
         Ipv6Addr { octets }
     }
+
+    /// Returns the sixteen eight-bit integers the IPv6 address consists of
+    /// as a slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip_as_octets)]
+    ///
+    /// use std::net::Ipv6Addr;
+    ///
+    /// assert_eq!(Ipv6Addr::new(0xff00, 0, 0, 0, 0, 0, 0, 0).as_octets(),
+    ///            &[255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
+    /// ```
+    #[unstable(feature = "ip_as_octets", issue = "137259")]
+    #[inline]
+    pub const fn as_octets(&self) -> &[u8; 16] {
+        &self.octets
+    }
 }
 
 /// Writes an Ipv6Addr, conforming to the canonical style described by