Description
openedon Jun 16, 2022
Proposal
Problem statement
Many times, there is a need for a simple dummy io::Read
er + io::Write
r, but currently the only options are io::Empty
and io::Sink
respectively. Having both of their functionality together requires writing your own boilerplate for something that makes sense to have in the standard library. This change adds the functionality of io::Sink
to io::Empty
, making io::Empty
be able to perform the tasks of both of the previous structs.
Motivation, use-cases
A simple idea for this is when a library requires a full stream, but as the developer, you don't really care about the output/input the library requires.
use std::io;
struct NeedsStream<S: io::Write + io::Read> {
stream: T,
}
impl<S: io::Write + io::Read> NeedsStream<S> {
fn new(s: S) -> Self { unimplemented!() }
// conducts some process, reading from the stream, and
// sending some output to it on events.
fn process(&mut self) -> bool { unimplemented!() }
}
// I just want the output `bool` of the processing, and
// don't care about the stream processing.
let mut n = io::null();
let ns = NeedsStream::new(n);
ns.process();
Solution sketches
I recently had a use for this, but I had to create my own entire struct for such a simple use case:
struct Null {
empty: Empty,
sink: Sink,
}
impl Write for Null {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.sink.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.sink.flush()
}
}
impl Read for Null {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.empty.read(buf)
}
}
Links and related work
Pull Request: rust-lang/rust#98154
This idea was proposed in rust-lang/rust#24235 from a quick search.
This idea is also similar to the /dev/null
on Unix.