about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2022-06-09 19:19:54 +0900
committerGitHub <noreply@github.com>2022-06-09 19:19:54 +0900
commitf14ccdbf6af63a0ee876821f11bd0d982e97818d (patch)
tree8f150d0aa1c7c3d96db9f1749f9bfb62aee120fe
parent6dc598a01b8f7619826b7152be5162e6d37a1754 (diff)
parent8b7a3f4d53f9e96a49d77ed42d22baf4d7743b94 (diff)
downloadrust-f14ccdbf6af63a0ee876821f11bd0d982e97818d.tar.gz
rust-f14ccdbf6af63a0ee876821f11bd0d982e97818d.zip
Rollup merge of #95632 - evanrichter:master, r=joshtriplett
impl Read and Write for VecDeque<u8>

Implementing `Read` and `Write` for `VecDeque<u8>` fills in the VecDeque api surface where `Vec<u8>` and `Cursor<Vec<u8>>` already impl Read and Write. Not only for completeness, but VecDeque in particular is a very handy mock interface for a TCP echo service, if only it supported Read/Write.

Since this PR is just an impl trait, I don't think there is a way to limit it behind a feature flag, so it's "insta-stable". Please correct me if I'm wrong here, not trying to rush stability.
-rw-r--r--library/std/src/io/impls.rs48
1 files changed, 48 insertions, 0 deletions
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index 64d2457bce1..0ca58efe1fe 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -3,6 +3,7 @@ mod tests;
 
 use crate::alloc::Allocator;
 use crate::cmp;
+use crate::collections::VecDeque;
 use crate::fmt;
 use crate::io::{
     self, BufRead, ErrorKind, IoSlice, IoSliceMut, Read, ReadBuf, Seek, SeekFrom, Write,
@@ -410,3 +411,50 @@ impl<A: Allocator> Write for Vec<u8, A> {
         Ok(())
     }
 }
+
+/// Read is implemented for `VecDeque<u8>` by consuming bytes from the front of the `VecDeque`.
+#[stable(feature = "vecdeque_read_write", since = "1.63.0")]
+impl<A: Allocator> Read for VecDeque<u8, A> {
+    /// Fill `buf` with the contents of the "front" slice as returned by
+    /// [`as_slices`][`VecDeque::as_slices`]. If the contained byte slices of the `VecDeque` are
+    /// discontiguous, multiple calls to `read` will be needed to read the entire content.
+    #[inline]
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        let (ref mut front, _) = self.as_slices();
+        let n = Read::read(front, buf)?;
+        self.drain(..n);
+        Ok(n)
+    }
+
+    #[inline]
+    fn read_buf(&mut self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
+        let (ref mut front, _) = self.as_slices();
+        let n = cmp::min(buf.remaining(), front.len());
+        Read::read_buf(front, buf)?;
+        self.drain(..n);
+        Ok(())
+    }
+}
+
+/// Write is implemented for `VecDeque<u8>` by appending to the `VecDeque`, growing it as needed.
+#[stable(feature = "vecdeque_read_write", since = "1.63.0")]
+impl<A: Allocator> Write for VecDeque<u8, A> {
+    #[inline]
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.reserve(buf.len());
+        self.extend(buf);
+        Ok(buf.len())
+    }
+
+    #[inline]
+    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+        self.reserve(buf.len());
+        self.extend(buf);
+        Ok(())
+    }
+
+    #[inline]
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}