Module async_lsp::stdio

source ·
Available on crate feature stdio and Unix only.
Expand description

Utilities to deal with stdin/stdout communication channel for Language Servers.

Typically Language Servers serves on stdin/stdout by default. But generally they cannot be read or written asynchronously usually, due to technical reasons. (Eg. tokio::io::stdin delegates reads to blocking threads.)

This mod defines PipeStdin and PipeStdout for only stdin/stdout with pipe-like backends, which actually supports asynchronous reads and writes. This currently means one of:

When calling PipeStdin::lock, it locks the stdin using std::io::stdin, set its mode to asynchronous, and exposes an a raw Read interface bypassing the std’s buffer.

Caveats

Since PipeStd{in,out} bypass the std’s internal buffer. You should not leave any data in that buffer (via std::io::stdin, print!-like macros and etc.). Otherwise they will be ignored during PipeStd{in,out} operations, which is typically a logic error.

Asynchrous I/O drivers

For runtime/drivers with uniform interfaces for sync-async conversion like async_io::Async, wrapping PipeStd{in,out} inside it just works.

use futures::AsyncWriteExt;

let mut stdout = async_io::Async::new(async_lsp::stdio::PipeStdout::lock()?)?;
stdout.write_all(b"truly async, without spawning blocking task!").await?;

For tokio runtime, their interface is less ergonomic. We provide a wrapper method PipeStdin::lock_tokio for an tokio::io::AsyncRead compatible interface. PipeStdout works in class. All of them are gated under feature tokio.

Structs