From a3a7d5cf91c4acbd2720c8bdcc9bb7ea5e450c01 Mon Sep 17 00:00:00 2001 From: Christofer Nolander Date: Fri, 3 May 2024 23:11:28 +0200 Subject: [PATCH] Add `std::io::IoSlice::as_slice` method This allows getting a slice with the same lifetime as the wrapped bytes. --- library/std/src/io/mod.rs | 28 +++++++++++++++++++++++ library/std/src/sys/pal/solid/io.rs | 2 +- library/std/src/sys/pal/unix/io.rs | 2 +- library/std/src/sys/pal/unsupported/io.rs | 2 +- library/std/src/sys/pal/wasi/io.rs | 2 +- library/std/src/sys/pal/windows/io.rs | 2 +- 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index a3fdcdc2d07ba..b70410c8758f9 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -1385,6 +1385,34 @@ impl<'a> IoSlice<'a> { IoSlice(sys::io::IoSlice::new(buf)) } + /// Returns a copy of the wrapped slice. + /// + /// The lifetime of the slice is not bound to the `IoSlice` itself, instead it references the + /// wrapped slice itself. This is unlike the slice which can be obtained from the [`Deref`] + /// implementation, its lifetime is tied to the specific `IoSlice`. This makes `as_slice` + /// suitable for changing the length of the slice in-place. + /// + /// # Examples + /// + /// ``` + /// #![feature(io_slice_as_slice)] + /// + /// use std::io::IoSlice; + /// + /// let data = [0, 1, 2, 3, 4]; + /// let mut buf = IoSlice::new(&data); + /// + /// // Discard the first and last bytes + /// buf = IoSlice::new(buf.as_slice()[1..4]); + /// assert_eq!(buf.as_slice(), [1, 2, 3].as_ref()); + /// ``` + #[unstable(feature = "io_slice_as_slice", issue = "124659")] + #[must_use] + #[inline] + pub fn as_slice(&self) -> &'a [u8] { + self.0.as_slice() + } + /// Advance the internal cursor of the slice. /// /// Also see [`IoSlice::advance_slices`] to advance the cursors of multiple diff --git a/library/std/src/sys/pal/solid/io.rs b/library/std/src/sys/pal/solid/io.rs index a862bb7870264..2ec1578dc43a9 100644 --- a/library/std/src/sys/pal/solid/io.rs +++ b/library/std/src/sys/pal/solid/io.rs @@ -33,7 +33,7 @@ impl<'a> IoSlice<'a> { } #[inline] - pub fn as_slice(&self) -> &[u8] { + pub fn as_slice(&self) -> &'a [u8] { unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) } } } diff --git a/library/std/src/sys/pal/unix/io.rs b/library/std/src/sys/pal/unix/io.rs index 29c340dd34942..aa6a9fe0dd621 100644 --- a/library/std/src/sys/pal/unix/io.rs +++ b/library/std/src/sys/pal/unix/io.rs @@ -33,7 +33,7 @@ impl<'a> IoSlice<'a> { } #[inline] - pub fn as_slice(&self) -> &[u8] { + pub fn as_slice(&self) -> &'a [u8] { unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) } } } diff --git a/library/std/src/sys/pal/unsupported/io.rs b/library/std/src/sys/pal/unsupported/io.rs index 6372fca74e0d7..7afcee3cb5dc9 100644 --- a/library/std/src/sys/pal/unsupported/io.rs +++ b/library/std/src/sys/pal/unsupported/io.rs @@ -15,7 +15,7 @@ impl<'a> IoSlice<'a> { } #[inline] - pub fn as_slice(&self) -> &[u8] { + pub fn as_slice(&self) -> &'a [u8] { self.0 } } diff --git a/library/std/src/sys/pal/wasi/io.rs b/library/std/src/sys/pal/wasi/io.rs index 2cd45df88fad1..c12e30e2ec748 100644 --- a/library/std/src/sys/pal/wasi/io.rs +++ b/library/std/src/sys/pal/wasi/io.rs @@ -30,7 +30,7 @@ impl<'a> IoSlice<'a> { } #[inline] - pub fn as_slice(&self) -> &[u8] { + pub fn as_slice(&self) -> &'a [u8] { unsafe { slice::from_raw_parts(self.vec.buf as *const u8, self.vec.buf_len) } } } diff --git a/library/std/src/sys/pal/windows/io.rs b/library/std/src/sys/pal/windows/io.rs index 77b8f3c410eb8..f5b7a0779dc02 100644 --- a/library/std/src/sys/pal/windows/io.rs +++ b/library/std/src/sys/pal/windows/io.rs @@ -35,7 +35,7 @@ impl<'a> IoSlice<'a> { } #[inline] - pub fn as_slice(&self) -> &[u8] { + pub fn as_slice(&self) -> &'a [u8] { unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) } } }