about summary refs log tree commit diff
path: root/library/std
diff options
context:
space:
mode:
authorJohn Millikin <john@john-millikin.com>2023-11-08 09:12:01 +0900
committerJohn Millikin <john@john-millikin.com>2023-11-09 07:10:11 +0900
commit341c85648c612532d757afb3cafa63ebaa3693db (patch)
tree883e3547b5f51760cd88b1dd0da37c2968644983 /library/std
parent90fdc1fc270fef7d1a999207f1da29b41da70dac (diff)
downloadrust-341c85648c612532d757afb3cafa63ebaa3693db.tar.gz
rust-341c85648c612532d757afb3cafa63ebaa3693db.zip
Move `BorrowedBuf` and `BorrowedCursor` from `std:io` to `core::io`
Assigned new feature name `core_io_borrowed_buf` to distinguish from the
`Read::read_buf` functionality in `std::io`.
Diffstat (limited to 'library/std')
-rw-r--r--library/std/src/io/impls.rs14
-rw-r--r--library/std/src/io/mod.rs3
-rw-r--r--library/std/src/io/readbuf.rs318
-rw-r--r--library/std/src/io/readbuf/tests.rs175
-rw-r--r--library/std/src/lib.rs1
5 files changed, 16 insertions, 495 deletions
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index f438325560f..256b043a609 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -528,3 +528,17 @@ impl<A: Allocator> Write for VecDeque<u8, A> {
         Ok(())
     }
 }
+
+#[unstable(feature = "read_buf", issue = "78485")]
+impl<'a> io::Write for core::io::BorrowedCursor<'a> {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        let amt = cmp::min(buf.len(), self.capacity());
+        self.append(&buf[..amt]);
+        Ok(amt)
+    }
+
+    #[inline]
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index aa9a2482d2d..7d70a0bac24 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -330,7 +330,7 @@ pub use self::{
 };
 
 #[unstable(feature = "read_buf", issue = "78485")]
-pub use self::readbuf::{BorrowedBuf, BorrowedCursor};
+pub use core::io::{BorrowedBuf, BorrowedCursor};
 pub(crate) use error::const_io_error;
 
 mod buffered;
@@ -339,7 +339,6 @@ mod cursor;
 mod error;
 mod impls;
 pub mod prelude;
-mod readbuf;
 mod stdio;
 mod util;
 
diff --git a/library/std/src/io/readbuf.rs b/library/std/src/io/readbuf.rs
deleted file mode 100644
index 95044de2a09..00000000000
--- a/library/std/src/io/readbuf.rs
+++ /dev/null
@@ -1,318 +0,0 @@
-#![unstable(feature = "read_buf", issue = "78485")]
-
-#[cfg(test)]
-mod tests;
-
-use crate::fmt::{self, Debug, Formatter};
-use crate::io::{Result, Write};
-use crate::mem::{self, MaybeUninit};
-use crate::{cmp, ptr};
-
-/// A borrowed byte buffer which is incrementally filled and initialized.
-///
-/// This type is a sort of "double cursor". It tracks three regions in the buffer: a region at the beginning of the
-/// buffer that has been logically filled with data, a region that has been initialized at some point but not yet
-/// logically filled, and a region at the end that is fully uninitialized. The filled region is guaranteed to be a
-/// subset of the initialized region.
-///
-/// In summary, the contents of the buffer can be visualized as:
-/// ```not_rust
-/// [             capacity              ]
-/// [ filled |         unfilled         ]
-/// [    initialized    | uninitialized ]
-/// ```
-///
-/// A `BorrowedBuf` is created around some existing data (or capacity for data) via a unique reference
-/// (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_init`), but cannot be
-/// directly written. To write into the buffer, use `unfilled` to create a `BorrowedCursor`. The cursor
-/// has write-only access to the unfilled portion of the buffer (you can think of it as a
-/// write-only iterator).
-///
-/// The lifetime `'data` is a bound on the lifetime of the underlying data.
-pub struct BorrowedBuf<'data> {
-    /// The buffer's underlying data.
-    buf: &'data mut [MaybeUninit<u8>],
-    /// The length of `self.buf` which is known to be filled.
-    filled: usize,
-    /// The length of `self.buf` which is known to be initialized.
-    init: usize,
-}
-
-impl Debug for BorrowedBuf<'_> {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        f.debug_struct("BorrowedBuf")
-            .field("init", &self.init)
-            .field("filled", &self.filled)
-            .field("capacity", &self.capacity())
-            .finish()
-    }
-}
-
-/// Create a new `BorrowedBuf` from a fully initialized slice.
-impl<'data> From<&'data mut [u8]> for BorrowedBuf<'data> {
-    #[inline]
-    fn from(slice: &'data mut [u8]) -> BorrowedBuf<'data> {
-        let len = slice.len();
-
-        BorrowedBuf {
-            // SAFETY: initialized data never becoming uninitialized is an invariant of BorrowedBuf
-            buf: unsafe { (slice as *mut [u8]).as_uninit_slice_mut().unwrap() },
-            filled: 0,
-            init: len,
-        }
-    }
-}
-
-/// Create a new `BorrowedBuf` from an uninitialized buffer.
-///
-/// Use `set_init` if part of the buffer is known to be already initialized.
-impl<'data> From<&'data mut [MaybeUninit<u8>]> for BorrowedBuf<'data> {
-    #[inline]
-    fn from(buf: &'data mut [MaybeUninit<u8>]) -> BorrowedBuf<'data> {
-        BorrowedBuf { buf, filled: 0, init: 0 }
-    }
-}
-
-impl<'data> BorrowedBuf<'data> {
-    /// Returns the total capacity of the buffer.
-    #[inline]
-    pub fn capacity(&self) -> usize {
-        self.buf.len()
-    }
-
-    /// Returns the length of the filled part of the buffer.
-    #[inline]
-    pub fn len(&self) -> usize {
-        self.filled
-    }
-
-    /// Returns the length of the initialized part of the buffer.
-    #[inline]
-    pub fn init_len(&self) -> usize {
-        self.init
-    }
-
-    /// Returns a shared reference to the filled portion of the buffer.
-    #[inline]
-    pub fn filled(&self) -> &[u8] {
-        // SAFETY: We only slice the filled part of the buffer, which is always valid
-        unsafe { MaybeUninit::slice_assume_init_ref(&self.buf[0..self.filled]) }
-    }
-
-    /// Returns a mutable reference to the filled portion of the buffer.
-    #[inline]
-    pub fn filled_mut(&mut self) -> &mut [u8] {
-        // SAFETY: We only slice the filled part of the buffer, which is always valid
-        unsafe { MaybeUninit::slice_assume_init_mut(&mut self.buf[0..self.filled]) }
-    }
-
-    /// Returns a cursor over the unfilled part of the buffer.
-    #[inline]
-    pub fn unfilled<'this>(&'this mut self) -> BorrowedCursor<'this> {
-        BorrowedCursor {
-            start: self.filled,
-            // SAFETY: we never assign into `BorrowedCursor::buf`, so treating its
-            // lifetime covariantly is safe.
-            buf: unsafe {
-                mem::transmute::<&'this mut BorrowedBuf<'data>, &'this mut BorrowedBuf<'this>>(self)
-            },
-        }
-    }
-
-    /// Clears the buffer, resetting the filled region to empty.
-    ///
-    /// The number of initialized bytes is not changed, and the contents of the buffer are not modified.
-    #[inline]
-    pub fn clear(&mut self) -> &mut Self {
-        self.filled = 0;
-        self
-    }
-
-    /// Asserts that the first `n` bytes of the buffer are initialized.
-    ///
-    /// `BorrowedBuf` assumes that bytes are never de-initialized, so this method does nothing when called with fewer
-    /// bytes than are already known to be initialized.
-    ///
-    /// # Safety
-    ///
-    /// The caller must ensure that the first `n` unfilled bytes of the buffer have already been initialized.
-    #[inline]
-    pub unsafe fn set_init(&mut self, n: usize) -> &mut Self {
-        self.init = cmp::max(self.init, n);
-        self
-    }
-}
-
-/// A writeable view of the unfilled portion of a [`BorrowedBuf`](BorrowedBuf).
-///
-/// Provides access to the initialized and uninitialized parts of the underlying `BorrowedBuf`.
-/// Data can be written directly to the cursor by using [`append`](BorrowedCursor::append) or
-/// indirectly by getting a slice of part or all of the cursor and writing into the slice. In the
-/// indirect case, the caller must call [`advance`](BorrowedCursor::advance) after writing to inform
-/// the cursor how many bytes have been written.
-///
-/// Once data is written to the cursor, it becomes part of the filled portion of the underlying
-/// `BorrowedBuf` and can no longer be accessed or re-written by the cursor. I.e., the cursor tracks
-/// the unfilled part of the underlying `BorrowedBuf`.
-///
-/// The lifetime `'a` is a bound on the lifetime of the underlying buffer (which means it is a bound
-/// on the data in that buffer by transitivity).
-#[derive(Debug)]
-pub struct BorrowedCursor<'a> {
-    /// The underlying buffer.
-    // Safety invariant: we treat the type of buf as covariant in the lifetime of `BorrowedBuf` when
-    // we create a `BorrowedCursor`. This is only safe if we never replace `buf` by assigning into
-    // it, so don't do that!
-    buf: &'a mut BorrowedBuf<'a>,
-    /// The length of the filled portion of the underlying buffer at the time of the cursor's
-    /// creation.
-    start: usize,
-}
-
-impl<'a> BorrowedCursor<'a> {
-    /// Reborrow this cursor by cloning it with a smaller lifetime.
-    ///
-    /// Since a cursor maintains unique access to its underlying buffer, the borrowed cursor is
-    /// not accessible while the new cursor exists.
-    #[inline]
-    pub fn reborrow<'this>(&'this mut self) -> BorrowedCursor<'this> {
-        BorrowedCursor {
-            // SAFETY: we never assign into `BorrowedCursor::buf`, so treating its
-            // lifetime covariantly is safe.
-            buf: unsafe {
-                mem::transmute::<&'this mut BorrowedBuf<'a>, &'this mut BorrowedBuf<'this>>(
-                    self.buf,
-                )
-            },
-            start: self.start,
-        }
-    }
-
-    /// Returns the available space in the cursor.
-    #[inline]
-    pub fn capacity(&self) -> usize {
-        self.buf.capacity() - self.buf.filled
-    }
-
-    /// Returns the number of bytes written to this cursor since it was created from a `BorrowedBuf`.
-    ///
-    /// Note that if this cursor is a reborrowed clone of another, then the count returned is the
-    /// count written via either cursor, not the count since the cursor was reborrowed.
-    #[inline]
-    pub fn written(&self) -> usize {
-        self.buf.filled - self.start
-    }
-
-    /// Returns a shared reference to the initialized portion of the cursor.
-    #[inline]
-    pub fn init_ref(&self) -> &[u8] {
-        // SAFETY: We only slice the initialized part of the buffer, which is always valid
-        unsafe { MaybeUninit::slice_assume_init_ref(&self.buf.buf[self.buf.filled..self.buf.init]) }
-    }
-
-    /// Returns a mutable reference to the initialized portion of the cursor.
-    #[inline]
-    pub fn init_mut(&mut self) -> &mut [u8] {
-        // SAFETY: We only slice the initialized part of the buffer, which is always valid
-        unsafe {
-            MaybeUninit::slice_assume_init_mut(&mut self.buf.buf[self.buf.filled..self.buf.init])
-        }
-    }
-
-    /// Returns a mutable reference to the uninitialized part of the cursor.
-    ///
-    /// It is safe to uninitialize any of these bytes.
-    #[inline]
-    pub fn uninit_mut(&mut self) -> &mut [MaybeUninit<u8>] {
-        &mut self.buf.buf[self.buf.init..]
-    }
-
-    /// Returns a mutable reference to the whole cursor.
-    ///
-    /// # Safety
-    ///
-    /// The caller must not uninitialize any bytes in the initialized portion of the cursor.
-    #[inline]
-    pub unsafe fn as_mut(&mut self) -> &mut [MaybeUninit<u8>] {
-        &mut self.buf.buf[self.buf.filled..]
-    }
-
-    /// Advance the cursor by asserting that `n` bytes have been filled.
-    ///
-    /// After advancing, the `n` bytes are no longer accessible via the cursor and can only be
-    /// accessed via the underlying buffer. I.e., the buffer's filled portion grows by `n` elements
-    /// and its unfilled portion (and the capacity of this cursor) shrinks by `n` elements.
-    ///
-    /// # Safety
-    ///
-    /// The caller must ensure that the first `n` bytes of the cursor have been properly
-    /// initialised.
-    #[inline]
-    pub unsafe fn advance(&mut self, n: usize) -> &mut Self {
-        self.buf.filled += n;
-        self.buf.init = cmp::max(self.buf.init, self.buf.filled);
-        self
-    }
-
-    /// Initializes all bytes in the cursor.
-    #[inline]
-    pub fn ensure_init(&mut self) -> &mut Self {
-        let uninit = self.uninit_mut();
-        // SAFETY: 0 is a valid value for MaybeUninit<u8> and the length matches the allocation
-        // since it is comes from a slice reference.
-        unsafe {
-            ptr::write_bytes(uninit.as_mut_ptr(), 0, uninit.len());
-        }
-        self.buf.init = self.buf.capacity();
-
-        self
-    }
-
-    /// Asserts that the first `n` unfilled bytes of the cursor are initialized.
-    ///
-    /// `BorrowedBuf` assumes that bytes are never de-initialized, so this method does nothing when
-    /// called with fewer bytes than are already known to be initialized.
-    ///
-    /// # Safety
-    ///
-    /// The caller must ensure that the first `n` bytes of the buffer have already been initialized.
-    #[inline]
-    pub unsafe fn set_init(&mut self, n: usize) -> &mut Self {
-        self.buf.init = cmp::max(self.buf.init, self.buf.filled + n);
-        self
-    }
-
-    /// Appends data to the cursor, advancing position within its buffer.
-    ///
-    /// # Panics
-    ///
-    /// Panics if `self.capacity()` is less than `buf.len()`.
-    #[inline]
-    pub fn append(&mut self, buf: &[u8]) {
-        assert!(self.capacity() >= buf.len());
-
-        // SAFETY: we do not de-initialize any of the elements of the slice
-        unsafe {
-            MaybeUninit::write_slice(&mut self.as_mut()[..buf.len()], buf);
-        }
-
-        // SAFETY: We just added the entire contents of buf to the filled section.
-        unsafe {
-            self.set_init(buf.len());
-        }
-        self.buf.filled += buf.len();
-    }
-}
-
-impl<'a> Write for BorrowedCursor<'a> {
-    fn write(&mut self, buf: &[u8]) -> Result<usize> {
-        let amt = cmp::min(buf.len(), self.capacity());
-        self.append(&buf[..amt]);
-        Ok(amt)
-    }
-
-    #[inline]
-    fn flush(&mut self) -> Result<()> {
-        Ok(())
-    }
-}
diff --git a/library/std/src/io/readbuf/tests.rs b/library/std/src/io/readbuf/tests.rs
deleted file mode 100644
index 89a2f6b2271..00000000000
--- a/library/std/src/io/readbuf/tests.rs
+++ /dev/null
@@ -1,175 +0,0 @@
-use super::BorrowedBuf;
-use crate::mem::MaybeUninit;
-
-/// Test that BorrowedBuf has the correct numbers when created with new
-#[test]
-fn new() {
-    let buf: &mut [_] = &mut [0; 16];
-    let mut rbuf: BorrowedBuf<'_> = buf.into();
-
-    assert_eq!(rbuf.filled().len(), 0);
-    assert_eq!(rbuf.init_len(), 16);
-    assert_eq!(rbuf.capacity(), 16);
-    assert_eq!(rbuf.unfilled().capacity(), 16);
-}
-
-/// Test that BorrowedBuf has the correct numbers when created with uninit
-#[test]
-fn uninit() {
-    let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16];
-    let mut rbuf: BorrowedBuf<'_> = buf.into();
-
-    assert_eq!(rbuf.filled().len(), 0);
-    assert_eq!(rbuf.init_len(), 0);
-    assert_eq!(rbuf.capacity(), 16);
-    assert_eq!(rbuf.unfilled().capacity(), 16);
-}
-
-#[test]
-fn initialize_unfilled() {
-    let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16];
-    let mut rbuf: BorrowedBuf<'_> = buf.into();
-
-    rbuf.unfilled().ensure_init();
-
-    assert_eq!(rbuf.init_len(), 16);
-}
-
-#[test]
-fn advance_filled() {
-    let buf: &mut [_] = &mut [0; 16];
-    let mut rbuf: BorrowedBuf<'_> = buf.into();
-
-    unsafe {
-        rbuf.unfilled().advance(1);
-    }
-
-    assert_eq!(rbuf.filled().len(), 1);
-    assert_eq!(rbuf.unfilled().capacity(), 15);
-}
-
-#[test]
-fn clear() {
-    let buf: &mut [_] = &mut [255; 16];
-    let mut rbuf: BorrowedBuf<'_> = buf.into();
-
-    unsafe {
-        rbuf.unfilled().advance(16);
-    }
-
-    assert_eq!(rbuf.filled().len(), 16);
-    assert_eq!(rbuf.unfilled().capacity(), 0);
-
-    rbuf.clear();
-
-    assert_eq!(rbuf.filled().len(), 0);
-    assert_eq!(rbuf.unfilled().capacity(), 16);
-
-    assert_eq!(rbuf.unfilled().init_ref(), [255; 16]);
-}
-
-#[test]
-fn set_init() {
-    let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16];
-    let mut rbuf: BorrowedBuf<'_> = buf.into();
-
-    unsafe {
-        rbuf.set_init(8);
-    }
-
-    assert_eq!(rbuf.init_len(), 8);
-
-    unsafe {
-        rbuf.unfilled().advance(4);
-    }
-
-    unsafe {
-        rbuf.set_init(2);
-    }
-
-    assert_eq!(rbuf.init_len(), 8);
-
-    unsafe {
-        rbuf.set_init(8);
-    }
-
-    assert_eq!(rbuf.init_len(), 8);
-}
-
-#[test]
-fn append() {
-    let buf: &mut [_] = &mut [MaybeUninit::new(255); 16];
-    let mut rbuf: BorrowedBuf<'_> = buf.into();
-
-    rbuf.unfilled().append(&[0; 8]);
-
-    assert_eq!(rbuf.init_len(), 8);
-    assert_eq!(rbuf.filled().len(), 8);
-    assert_eq!(rbuf.filled(), [0; 8]);
-
-    rbuf.clear();
-
-    rbuf.unfilled().append(&[1; 16]);
-
-    assert_eq!(rbuf.init_len(), 16);
-    assert_eq!(rbuf.filled().len(), 16);
-    assert_eq!(rbuf.filled(), [1; 16]);
-}
-
-#[test]
-fn reborrow_written() {
-    let buf: &mut [_] = &mut [MaybeUninit::new(0); 32];
-    let mut buf: BorrowedBuf<'_> = buf.into();
-
-    let mut cursor = buf.unfilled();
-    cursor.append(&[1; 16]);
-
-    let mut cursor2 = cursor.reborrow();
-    cursor2.append(&[2; 16]);
-
-    assert_eq!(cursor2.written(), 32);
-    assert_eq!(cursor.written(), 32);
-
-    assert_eq!(buf.unfilled().written(), 0);
-    assert_eq!(buf.init_len(), 32);
-    assert_eq!(buf.filled().len(), 32);
-    let filled = buf.filled();
-    assert_eq!(&filled[..16], [1; 16]);
-    assert_eq!(&filled[16..], [2; 16]);
-}
-
-#[test]
-fn cursor_set_init() {
-    let buf: &mut [_] = &mut [MaybeUninit::uninit(); 16];
-    let mut rbuf: BorrowedBuf<'_> = buf.into();
-
-    unsafe {
-        rbuf.unfilled().set_init(8);
-    }
-
-    assert_eq!(rbuf.init_len(), 8);
-    assert_eq!(rbuf.unfilled().init_ref().len(), 8);
-    assert_eq!(rbuf.unfilled().init_mut().len(), 8);
-    assert_eq!(rbuf.unfilled().uninit_mut().len(), 8);
-    assert_eq!(unsafe { rbuf.unfilled().as_mut() }.len(), 16);
-
-    unsafe {
-        rbuf.unfilled().advance(4);
-    }
-
-    unsafe {
-        rbuf.unfilled().set_init(2);
-    }
-
-    assert_eq!(rbuf.init_len(), 8);
-
-    unsafe {
-        rbuf.unfilled().set_init(8);
-    }
-
-    assert_eq!(rbuf.init_len(), 12);
-    assert_eq!(rbuf.unfilled().init_ref().len(), 8);
-    assert_eq!(rbuf.unfilled().init_mut().len(), 8);
-    assert_eq!(rbuf.unfilled().uninit_mut().len(), 4);
-    assert_eq!(unsafe { rbuf.unfilled().as_mut() }.len(), 12);
-}
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index f57c8d4e7e2..42589012257 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -310,6 +310,7 @@
 // tidy-alphabetical-start
 #![feature(char_internals)]
 #![feature(core_intrinsics)]
+#![feature(core_io_borrowed_buf)]
 #![feature(duration_constants)]
 #![feature(error_generic_member_access)]
 #![feature(error_in_core)]