Skip to content

Commit

Permalink
Add as_slice/into_slice for IoSlice/IoSliceMut.
Browse files Browse the repository at this point in the history
Co-authored-by: Mike Pedersen <[email protected]>
Co-authored-by: Nathan West <[email protected]>
  • Loading branch information
3 people committed Nov 8, 2024
1 parent b27f33a commit 34e2616
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 6 deletions.
45 changes: 45 additions & 0 deletions library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1340,6 +1340,25 @@ impl<'a> IoSliceMut<'a> {
bufs[0].advance(left);
}
}

/// Get the underlying bytes as a mutable slice with the original lifetime.
///
/// # Examples
///
/// ```
/// #![feature(io_slice_as_bytes)]
/// use std::io::IoSliceMut;
///
/// let mut data = *b"abcdef";
/// let io_slice = IoSliceMut::new(&mut data);
/// io_slice.into_slice()[0] = b'A';
///
/// assert_eq!(&data, b"Abcdef");
/// ```
#[unstable(feature = "io_slice_as_bytes", issue = "111277")]
pub const fn into_slice(self) -> &'a mut [u8] {
self.0.into_slice()
}
}

#[stable(feature = "iovec", since = "1.36.0")]
Expand Down Expand Up @@ -1482,6 +1501,32 @@ impl<'a> IoSlice<'a> {
bufs[0].advance(left);
}
}

/// Get the underlying bytes as a slice with the original lifetime.
///
/// This doesn't borrow from `self`, so is less restrictive than calling
/// `.deref()`, which does.
///
/// # Examples
///
/// ```
/// #![feature(io_slice_as_bytes)]
/// use std::io::IoSlice;
///
/// let data = b"abcdef";
///
/// let mut io_slice = IoSlice::new(data);
/// let tail = &io_slice.as_slice()[3..];
///
/// // This works because `tail` doesn't borrow `io_slice`
/// io_slice = IoSlice::new(tail);
///
/// assert_eq!(io_slice.as_slice(), b"def");
/// ```
#[unstable(feature = "io_slice_as_bytes", issue = "111277")]
pub const fn as_slice(self) -> &'a [u8] {
self.0.as_slice()
}
}

#[stable(feature = "iovec", since = "1.36.0")]
Expand Down
14 changes: 14 additions & 0 deletions library/std/src/io/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,20 @@ fn io_slice_advance_slices_beyond_total_length() {
assert!(bufs.is_empty());
}

#[test]
fn io_slice_as_slice() {
let buf = [1; 8];
let slice = IoSlice::new(&buf).as_slice();
assert_eq!(slice, buf);
}

#[test]
fn io_slice_into_slice() {
let mut buf = [1; 8];
let slice = IoSliceMut::new(&mut buf).into_slice();
assert_eq!(slice, [1; 8]);
}

/// Creates a new writer that reads from at most `n_bufs` and reads
/// `per_call` bytes (in total) per call to write.
fn test_writer(n_bufs: usize, per_call: usize) -> TestWriter {
Expand Down
7 changes: 6 additions & 1 deletion library/std/src/sys/pal/hermit/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl<'a> IoSlice<'a> {
}

#[inline]
pub fn as_slice(&self) -> &[u8] {
pub const fn as_slice(&self) -> &'a [u8] {
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}
}
Expand Down Expand Up @@ -70,6 +70,11 @@ impl<'a> IoSliceMut<'a> {
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}

#[inline]
pub const fn into_slice(self) -> &'a mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
Expand Down
7 changes: 6 additions & 1 deletion library/std/src/sys/pal/solid/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl<'a> IoSlice<'a> {
}

#[inline]
pub fn as_slice(&self) -> &[u8] {
pub const fn as_slice(&self) -> &'a [u8] {
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}
}
Expand Down Expand Up @@ -70,6 +70,11 @@ impl<'a> IoSliceMut<'a> {
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}

#[inline]
pub const fn into_slice(self) -> &'a mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
Expand Down
7 changes: 6 additions & 1 deletion library/std/src/sys/pal/unix/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl<'a> IoSlice<'a> {
}

#[inline]
pub fn as_slice(&self) -> &[u8] {
pub const fn as_slice(&self) -> &'a [u8] {
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}
}
Expand Down Expand Up @@ -70,6 +70,11 @@ impl<'a> IoSliceMut<'a> {
unsafe { slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}

#[inline]
pub const fn into_slice(self) -> &'a mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
Expand Down
7 changes: 6 additions & 1 deletion library/std/src/sys/pal/unsupported/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl<'a> IoSlice<'a> {
}

#[inline]
pub fn as_slice(&self) -> &[u8] {
pub const fn as_slice(&self) -> &'a [u8] {
self.0
}
}
Expand All @@ -40,6 +40,11 @@ impl<'a> IoSliceMut<'a> {
self.0
}

#[inline]
pub const fn into_slice(self) -> &'a mut [u8] {
self.0
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
self.0
Expand Down
7 changes: 6 additions & 1 deletion library/std/src/sys/pal/wasi/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl<'a> IoSlice<'a> {
}

#[inline]
pub fn as_slice(&self) -> &[u8] {
pub const fn as_slice(&self) -> &'a [u8] {
unsafe { slice::from_raw_parts(self.vec.buf as *const u8, self.vec.buf_len) }
}
}
Expand Down Expand Up @@ -67,6 +67,11 @@ impl<'a> IoSliceMut<'a> {
unsafe { slice::from_raw_parts(self.vec.buf as *const u8, self.vec.buf_len) }
}

#[inline]
pub const fn into_slice(self) -> &'a mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.buf as *mut u8, self.vec.buf_len) }
Expand Down
7 changes: 6 additions & 1 deletion library/std/src/sys/pal/windows/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl<'a> IoSlice<'a> {
}

#[inline]
pub fn as_slice(&self) -> &[u8] {
pub const fn as_slice(&self) -> &'a [u8] {
unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) }
}
}
Expand Down Expand Up @@ -74,6 +74,11 @@ impl<'a> IoSliceMut<'a> {
unsafe { slice::from_raw_parts(self.vec.buf, self.vec.len as usize) }
}

#[inline]
pub const fn into_slice(self) -> &'a mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len) }
}

#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.vec.buf, self.vec.len as usize) }
Expand Down

0 comments on commit 34e2616

Please sign in to comment.