我想从当前进程的STDIN中异步读取,转换读取的数据,然后将其泵送到子进程(使用std::process::Command::new
创建)。我尝试这样做,如下所示:
fn transform_input(buff: &[u8]) -> Vec<u8> {
unimplemented!()
}
async fn read_stdin<'a>(
child_stdin: &'a mut ChildStdin,
buff: &'a mut [u8],
) -> Result<bool, std::io::Error> {
// async read from parent stdin
let (_, bff, sz) = await!(tokio::io::read(tokio::io::stdin(), buff));
// transform data
let transformed = transform_input(bff);
// pump to stdin of child process
match child_stdin.write_all(bff) {
// if # bytes read from parent input < 1, EOF/closed input stream
Ok(()) => Ok(sz < 1),
Err(e) => Err(e),
}
}
无法编译:
error[E0277]: the trait bound `tokio_io::io::read::Read<tokio::io::Stdin, &mut [u8]>: std::future::Future` is not satisfied
--> src/main.rs:25:24
|
25 | let (_, bff, sz) = await!(tokio::io::read(tokio::io::stdin(), buff));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `tokio_io::io::read::Read<tokio::io::Stdin, &mut [u8]>`
|
= note: required by `std::future::poll_with_tls_waker`
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
如何成功从STDIN异步读取?
该程序的目的是包装任意外部CLI工具,将控制通道注入stdin,以使elixir代码更好地控制外部程序,并将stderr和stdout分成两个不同的流(按照瓷器/ erlexec的样式)。我看不到需要多个OS级别的线程-该程序将花费大部分时间等待来自stdin的输入或子进程的stdout / stderr的输出,在接收到数据时执行廉价且快速的操作。这是所需的控制流程:
我认为由epoll
之类的东西支持的单线程循环比开始新线程要好得多,并且我知道tokio stdin依赖这种机制。但是,要获得可靠的异步锈蚀和Tokio使用指南似乎非常困难,许多人指出该地区变化如此之快,以至于那些指南很快就过时了。过去,我只编写了一些防锈程序,所以知道我很可能会错过一些基本知识并感谢您的帮助。令我感到羞耻的是,我什至不清楚编译错误消息的含义-看起来东京期货和标准期货不兼容,但我认为应该是这样。