Skip to content

Commit

Permalink
Rollup merge of #95632 - evanrichter:master, r=joshtriplett
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
JohnTitor committed Jun 9, 2022
2 parents 6dc598a + 8b7a3f4 commit f14ccdb
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions library/std/src/io/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(())
}
}

0 comments on commit f14ccdb

Please sign in to comment.