io-streams 0.2.0

Unbuffered and unlocked I/O streams
Documentation

This crate defines StreamReader, StreamWriter, and StreamDuplexer types which provide safe, owning, unbuffered, and unlocked access to a raw I/O stream, such as standard input, standard output, files, sockets, or pipes. It also supports a "piped thread" concept, where an arbitrary Box<dyn Read + Send> or Box<dyn Write + Send> can be provided, and the I/O is performed on a thread and connecting to the StreamReader or StreamWriter with a pipe, and a "socketed thread" concept, where a provided function is called on a thread and connected to the main thread via a bidirectional socket.

On Posix-ish platforms, including limited support for WASI, these types just contain a single file descriptor (and implement AsRawFd), plus any resources needed to safely hold the file descriptor live. On Windows, they contain an enum holding either RawHandle or RawSocket.

Since these types are unbuffered, it's advisable for most use cases to wrap them in buffering types such as std::io::BufReader, std::io::BufWriter, std::io::LineWriter, io_streams::BufDuplexer, or io_streams::BufReaderLineWriter.

Rust's std::io::Stdin and std::io::Stdout are always buffered, while its std::fs::File and std::net::TcpStream are unbuffered. A key purpose of the io_streams crate is to abstract over the underlying inputs and outputs without adding buffering, so that buffering can be applied without redundancy.

This crate locks stdio::io::Stdin and std::io::Stdout while it has their corresponding streams open, to prevent accidental mixing of buffered and unbuffered output on the same stream. Attempts to use the buffered streams when they are locked will block indefinitely.