about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVidhan Bhatt <me@vidhan.io>2023-05-05 09:32:33 -0400
committerVidhan Bhatt <me@vidhan.io>2023-05-05 09:32:33 -0400
commit79a22f4954704d65f8356be59c3d07851e31f074 (patch)
tree28a24ecff0e8f10131e45b18ae88ec22ffefa1d5
parentdd9a7bf848e412c81e3045245acbd5a01641a610 (diff)
downloadrust-79a22f4954704d65f8356be59c3d07851e31f074.tar.gz
rust-79a22f4954704d65f8356be59c3d07851e31f074.zip
feat: merge functionality of `io::Sink` into `io::Empty`
-rw-r--r--library/std/src/io/util.rs100
-rw-r--r--library/std/src/io/util/tests.rs13
2 files changed, 87 insertions, 26 deletions
diff --git a/library/std/src/io/util.rs b/library/std/src/io/util.rs
index f076ee0923c..202c0a9a69c 100644
--- a/library/std/src/io/util.rs
+++ b/library/std/src/io/util.rs
@@ -8,24 +8,41 @@ use crate::io::{
     self, BorrowedCursor, BufRead, IoSlice, IoSliceMut, Read, Seek, SeekFrom, SizeHint, Write,
 };
 
-/// A reader which is always at EOF.
+/// `Empty` ignores any data written via [`Write`], and will always be empty
+/// (returning zero bytes) when read via [`Read`].
 ///
-/// This struct is generally created by calling [`empty()`]. Please see
-/// the documentation of [`empty()`] for more details.
+/// This struct is generally created by calling [`empty()`]. Please
+/// see the documentation of [`empty()`] for more details.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[non_exhaustive]
-#[derive(Copy, Clone, Default)]
+#[derive(Copy, Clone, Debug, Default)]
 pub struct Empty;
 
-/// Constructs a new handle to an empty reader.
+/// Creates a value that is always at EOF for reads, and ignores all data written.
 ///
-/// All reads from the returned reader will return <code>[Ok]\(0)</code>.
+/// All calls to [`write`] on the returned instance will return [`Ok(buf.len())`]
+/// and the contents of the buffer will not be inspected.
+///
+/// All calls to [`read`] from the returned reader will return [`Ok(0)`].
+///
+/// [`Ok(buf.len())`]: Ok
+/// [`Ok(0)`]: Ok
+///
+/// [`write`]: Write::write
+/// [`read`]: Read::read
 ///
 /// # Examples
 ///
-/// A slightly sad example of not reading anything into a buffer:
+/// ```rust
+/// use std::io::{self, Write};
 ///
+/// let buffer = vec![1, 2, 3, 5, 8];
+/// let num_bytes = io::empty().write(&buffer).unwrap();
+/// assert_eq!(num_bytes, 5);
 /// ```
+///
+///
+/// ```rust
 /// use std::io::{self, Read};
 ///
 /// let mut buffer = String::new();
@@ -76,13 +93,6 @@ impl Seek for Empty {
     }
 }
 
-#[stable(feature = "std_debug", since = "1.16.0")]
-impl fmt::Debug for Empty {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Empty").finish_non_exhaustive()
-    }
-}
-
 impl SizeHint for Empty {
     #[inline]
     fn upper_bound(&self) -> Option<usize> {
@@ -90,6 +100,54 @@ impl SizeHint for Empty {
     }
 }
 
+#[stable(feature = "empty_write", since = "1.64.0")]
+impl Write for Empty {
+    #[inline]
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        Ok(buf.len())
+    }
+
+    #[inline]
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        let total_len = bufs.iter().map(|b| b.len()).sum();
+        Ok(total_len)
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
+    }
+
+    #[inline]
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+#[stable(feature = "empty_write", since = "1.64.0")]
+impl Write for &Empty {
+    #[inline]
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        Ok(buf.len())
+    }
+
+    #[inline]
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        let total_len = bufs.iter().map(|b| b.len()).sum();
+        Ok(total_len)
+    }
+
+    #[inline]
+    fn is_write_vectored(&self) -> bool {
+        true
+    }
+
+    #[inline]
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
 /// A reader which yields one byte over and over and over and over and over and...
 ///
 /// This struct is generally created by calling [`repeat()`]. Please
@@ -182,19 +240,20 @@ impl fmt::Debug for Repeat {
 
 /// A writer which will move data into the void.
 ///
-/// This struct is generally created by calling [`sink`]. Please
+/// This struct is generally created by calling [`sink()`]. Please
 /// see the documentation of [`sink()`] for more details.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[non_exhaustive]
-#[derive(Copy, Clone, Default)]
+#[derive(Copy, Clone, Debug, Default)]
 pub struct Sink;
 
 /// Creates an instance of a writer which will successfully consume all data.
 ///
-/// All calls to [`write`] on the returned instance will return `Ok(buf.len())`
+/// All calls to [`write`] on the returned instance will return [`Ok(buf.len())`]
 /// and the contents of the buffer will not be inspected.
 ///
 /// [`write`]: Write::write
+/// [`Ok(buf.len())`]: Ok
 ///
 /// # Examples
 ///
@@ -259,10 +318,3 @@ impl Write for &Sink {
         Ok(())
     }
 }
-
-#[stable(feature = "std_debug", since = "1.16.0")]
-impl fmt::Debug for Sink {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Sink").finish_non_exhaustive()
-    }
-}
diff --git a/library/std/src/io/util/tests.rs b/library/std/src/io/util/tests.rs
index ce5e2c9da1d..2d0f97c74cf 100644
--- a/library/std/src/io/util/tests.rs
+++ b/library/std/src/io/util/tests.rs
@@ -77,7 +77,7 @@ fn empty_reads() {
     assert_eq!(e.read(&mut []).unwrap(), 0);
     assert_eq!(e.read(&mut [0]).unwrap(), 0);
     assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0);
-    assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0);
+    assert_eq!(Read::by_ref(&mut e).read(&mut [0; 1024]).unwrap(), 0);
 
     let buf: &mut [MaybeUninit<_>] = &mut [];
     let mut buf: BorrowedBuf<'_> = buf.into();
@@ -99,7 +99,7 @@ fn empty_reads() {
 
     let buf: &mut [_] = &mut [MaybeUninit::uninit(); 1024];
     let mut buf: BorrowedBuf<'_> = buf.into();
-    e.by_ref().read_buf(buf.unfilled()).unwrap();
+    Read::by_ref(&mut e).read_buf(buf.unfilled()).unwrap();
     assert_eq!(buf.len(), 0);
     assert_eq!(buf.init_len(), 0);
 }
@@ -125,6 +125,15 @@ fn empty_seeks() {
 }
 
 #[test]
+fn empty_sinks() {
+    let mut e = empty();
+    assert_eq!(e.write(&[]).unwrap(), 0);
+    assert_eq!(e.write(&[0]).unwrap(), 1);
+    assert_eq!(e.write(&[0; 1024]).unwrap(), 1024);
+    assert_eq!(Write::by_ref(&mut e).write(&[0; 1024]).unwrap(), 1024);
+}
+
+#[test]
 fn repeat_repeats() {
     let mut r = repeat(4);
     let mut b = [0; 1024];