Description
This tracks the status of specializing optional methods in implementations of io::Read
and io::Write
in the standard library.
Read
and Write
have many methods which are provided by default, and many implementors do not override them, which can be problematic in some cases. Platform abstractions for stdio are particularly lacking; most of which do not have read_buf
, so the buffer is forced to be initialized, and some platforms which support it might be missing vectored read/write. Since the standard library is general, this should be consistent.
I am working on addressing these gaps and have created this issue to track progress.
This surveys of all implementations of io::Read
and io::Write
in rust-lang/rust
, including for private types, by searching for \b(Read|Write) for
in .rs files. This should have no false negatives, as opposed to viewing references, which would omit other targets.
Additionally, I include all platform implementations of File
. These define read
, read_buf
, read_vectored
, is_read_vectored
, write
, write_vectored
, is_write_vectored
, and flush
as inherent methods. Since the other methods are not currently supported with this scheme, I have marked them with N/A.
Implementation history
PRs created for this effort and some relevant PRs from earlier:
- std: Update the std::io adaptors to proxy all methods #22428
- Add vectored read and write support #58357
- Add vectored positioned I/O on Unix #89518
- Add Read Impl for &Stdin #99153
- Specialize some methods of
io::Chain
#105917 - Implement read_buf for a few more types #108326
- Implement read_buf for RustHermit #109722
- Specialize some
io::Read
andio::Write
methods forVecDeque<u8>
and&[u8]
#110608 - Specialize many implementations of
Read::read_buf_exact
#122393 - Improve several
Read
implementations #122441 UnixStream
: overrideread_buf
#123084- Specialize
read_exact
andread_buf_exact
forVecDeque
#132039 - Provide optional
Read
/Write
methods for stdio #136769 - Implement
read*_exact
forstd:io::repeat
#136818 - Implement
write_all_vectored
forVecDeque
#136819 - Implement default methods for
io::Empty
andio::Sink
#137051 - Forward all default methods for I/O impls #137062
- Override default
Write
methods for cursor-like types #137107 - Implement
read_buf
for zkVM stdin #137349 - Implement
read_buf
for WASI stdin #137353 - Implement
read_buf
and vectored read/write for SGX stdio #137355 - Reserve before
write_fmt
for owned buffers #137762 - Implement
read_buf
for Hermit #138301 - Trusty: Implement
write_vectored
for stdio #138876
Read
pub trait Read {
fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> { … }
fn read_buf_exact(&mut self, buf: BorrowedCursor<'_>) -> Result<()> { … }
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> { … }
fn is_read_vectored(&self) -> bool { … } // considered with `read_vectored`
fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { … }
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> { … }
fn read_to_string(&mut self, buf: &mut String) -> Result<usize> { … }
}
Write
pub trait Write {
fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> { … }
fn is_write_vectored(&self) -> bool { … } // considered with `write_vectored`
fn write_all(&mut self, buf: &[u8]) -> Result<()> { … }
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<()> { … }
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> { … }
fn flush(&mut self) -> Result<()>;
}
FileExt
Type | read_at |
seek_read |
read_vectored_at |
read_exact_at |
write_at |
seek_write |
write_vectored_at |
write_all_at |
---|---|---|---|---|---|---|---|---|
std::fs::unix::fs::File |
✅ | N/A | ✅29 | default | ✅ | N/A | ✅29 | default |
std::sys::wasi::fs::File |
default | N/A | ✅ | default | default | N/A | ✅ | default |
std::sys::windows::fs::File |
N/A | ✅ | N/A | N/A | N/A | ✅ | N/A | N/A |
Socket
Type | read |
read_buf |
read_vectored |
recv_from |
peek |
peek_from |
write |
write_vectored |
---|---|---|---|---|---|---|---|---|
std::sys::net::hermit::Socket |
✅ | ✅30 | ✅/✅4 | ✅ | ✅ | ✅ | ✅ | ✅/✅4 |
std::sys::net::solid::Socket |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | |
std::sys::net::unix::Socket |
✅ | ✅13 | ✅3 4 | ✅ | ✅ | ✅ | ✅ | ✅3 4 |
std::sys::net::wasip2::Socket |
✅ | ✅ | default | ✅ | ✅ | ✅ | private | default |
std::sys::net::windows::Socket |
✅ | ✅13 | ✅3 4 | ✅ | ✅ | ✅ | ✅3 4 | |
std::sys::net::sgx::{TcpStream, UdpSocket} |
✅ | ✅20 | ✅3 4 | unsupported | unsupported (ok) | unsupported | ✅ | ✅3 4 |
std::sys::net::wasip1::{TcpStream, UdpSocket} |
✅ | ✅13 | ✅3 4 | unsupported | unsupported | unsupported | ✅ | ✅3 4 |
Footnotes
-
Added in Implement most of RFC 2930, providing the ReadBuf abstraction #81156. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14
-
Added in Specialize many implementations of
Read::read_buf_exact
#122393. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 -
Added in Add vectored read and write support #58357. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18 ↩19 ↩20 ↩21 ↩22 ↩23 ↩24 ↩25 ↩26 ↩27 ↩28 ↩29 ↩30 ↩31 ↩32 ↩33
-
Added in Add Read/Write::can_read/write_vectored #67841. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18 ↩19 ↩20 ↩21 ↩22 ↩23 ↩24 ↩25 ↩26 ↩27 ↩28 ↩29 ↩30 ↩31 ↩32 ↩33 ↩34 ↩35 ↩36 ↩37 ↩38 ↩39 ↩40 ↩41 ↩42 ↩43 ↩44 ↩45 ↩46 ↩47 ↩48 ↩49 ↩50 ↩51 ↩52 ↩53 ↩54 ↩55 ↩56 ↩57 ↩58 ↩59 ↩60 ↩61 ↩62
-
Added in std: Update the std::io adaptors to proxy all methods #22428. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Added in std: Stabilize portions of the
io
module #23010. ↩ ↩2 ↩3 ↩4 -
Added in Specialize some
io::Read
andio::Write
methods forVecDeque<u8>
and&[u8]
#110608. ↩ ↩2 ↩3 ↩4 -
Added in Specialize
read_exact
andread_buf_exact
forVecDeque
#132039. ↩ ↩2 -
Added in Specialize some methods of
io::Chain
#105917. ↩ ↩2 ↩3 -
Added in Implement default methods for
io::Empty
andio::Sink
#137051. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 -
Added in Implement
read*_exact
forstd:io::repeat
#136818. ↩ ↩2 -
Added in Improve several
Read
implementations #122441. ↩ ↩2 ↩3 -
Added in Implement read_buf for a few more types #108326. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12
-
Added in
UnixStream
: overrideread_buf
#123084. ↩ ↩2 -
This
Read
implementation is unused. I plan to remove it. ↩ -
Added in Implement
read_buf
for Hermit #138301. ↩ -
This
Read
implementation is unused. I plan to remove it. ↩ -
Added in Add Read Impl for &Stdin #99153. ↩
-
Added in Provide optional
Read
/Write
methods for stdio #136769. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 -
Added in Implement
read_buf
and vectored read/write for SGX stdio #137355. ↩ ↩2 ↩3 ↩4 ↩5 -
Added in Implement
read_buf
for WASI stdin #137353. ↩ -
Added in Implement
read_buf
for zkVM stdin #137349. ↩ -
Added in Forward all default methods for I/O impls #137062. ↩ ↩2
-
Added in Override default
Write
methods for cursor-like types #137107. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 -
StdoutLock<'_>
andStderrLock<'_>
cannot providewrite_fmt
, because the user could supply a formatting implementation which usesStdout
orStderr
, leading to panicking. (See joboet's comment) ↩ ↩2 -
SOLID has no vectored version of
SOLID_LOG_write
. ↩ -
TEEOS has no vectored version of
KCALL_DEBUG_CMD_PUT_BYTES
. ↩ -
Added in Add vectored positioned I/O on Unix #89518. ↩ ↩2
-
Added in Implement read_buf for RustHermit #109722. ↩