mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
73 lines
2.1 KiB
Rust
73 lines
2.1 KiB
Rust
use std::process::ExitStatus;
|
|
|
|
use mlua::prelude::*;
|
|
use tokio::{
|
|
io::{self, AsyncRead, AsyncReadExt},
|
|
process::Child,
|
|
task,
|
|
};
|
|
|
|
use super::{options::ProcessSpawnOptionsStdioKind, tee_writer::AsyncTeeWriter};
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub(super) struct WaitForChildResult {
|
|
pub status: ExitStatus,
|
|
pub stdout: Vec<u8>,
|
|
pub stderr: Vec<u8>,
|
|
}
|
|
|
|
async fn read_with_stdio_kind<R>(
|
|
read_from: Option<R>,
|
|
kind: ProcessSpawnOptionsStdioKind,
|
|
) -> LuaResult<Vec<u8>>
|
|
where
|
|
R: AsyncRead + Unpin,
|
|
{
|
|
Ok(match kind {
|
|
ProcessSpawnOptionsStdioKind::None | ProcessSpawnOptionsStdioKind::Forward => Vec::new(),
|
|
ProcessSpawnOptionsStdioKind::Default => {
|
|
let mut read_from =
|
|
read_from.expect("read_from must be Some when stdio kind is Default");
|
|
|
|
let mut buffer = Vec::new();
|
|
|
|
read_from.read_to_end(&mut buffer).await.into_lua_err()?;
|
|
|
|
buffer
|
|
}
|
|
ProcessSpawnOptionsStdioKind::Inherit => {
|
|
let mut read_from =
|
|
read_from.expect("read_from must be Some when stdio kind is Inherit");
|
|
|
|
let mut stdout = io::stdout();
|
|
let mut tee = AsyncTeeWriter::new(&mut stdout);
|
|
|
|
io::copy(&mut read_from, &mut tee).await.into_lua_err()?;
|
|
|
|
tee.into_vec()
|
|
}
|
|
})
|
|
}
|
|
|
|
pub(super) async fn wait_for_child(
|
|
mut child: Child,
|
|
stdout_kind: ProcessSpawnOptionsStdioKind,
|
|
stderr_kind: ProcessSpawnOptionsStdioKind,
|
|
) -> LuaResult<WaitForChildResult> {
|
|
let stdout_opt = child.stdout.take();
|
|
let stderr_opt = child.stderr.take();
|
|
|
|
let stdout_task = task::spawn(read_with_stdio_kind(stdout_opt, stdout_kind));
|
|
let stderr_task = task::spawn(read_with_stdio_kind(stderr_opt, stderr_kind));
|
|
|
|
let status = child.wait().await.expect("Child process failed to start");
|
|
|
|
let stdout_buffer = stdout_task.await.into_lua_err()??;
|
|
let stderr_buffer = stderr_task.await.into_lua_err()??;
|
|
|
|
Ok(WaitForChildResult {
|
|
status,
|
|
stdout: stdout_buffer,
|
|
stderr: stderr_buffer,
|
|
})
|
|
}
|