asimov_runner/programs/
runner.rs1use crate::{Executor, ExecutorError, Input, Output};
4use async_trait::async_trait;
5use derive_more::Debug;
6use std::{
7 ffi::OsStr,
8 io::{Cursor, Read},
9 process::Stdio,
10};
11use tokio::io::{AsyncRead, AsyncWrite};
12
13pub use asimov_patterns::RunnerOptions;
14
15pub type RunnerResult = std::result::Result<Cursor<Vec<u8>>, ExecutorError>; #[allow(unused)]
20#[derive(Debug)]
21pub struct Runner {
22 executor: Executor,
23 options: RunnerOptions,
24 input: Input,
25 output: Output,
26}
27
28impl Runner {
29 pub fn new(
30 program: impl AsRef<OsStr>,
31 input: Input,
32 output: Output,
33 options: RunnerOptions,
34 ) -> Self {
35 let mut executor = Executor::new(program);
36 executor
37 .command()
38 .args(
39 &options
40 .define
41 .iter()
42 .map(|(k, v)| format!("--define={}={}", k, v))
43 .collect::<Vec<_>>(),
44 )
45 .args(&options.other)
46 .stdin(input.as_stdio())
47 .stdout(output.as_stdio())
48 .stderr(Stdio::piped());
49
50 Self {
51 executor,
52 options,
53 input,
54 output,
55 }
56 }
57
58 pub async fn execute(&mut self) -> RunnerResult {
59 let stdout = self.executor.execute_with_input(&mut self.input).await?;
60 Ok(stdout)
61 }
62}
63
64impl asimov_patterns::Runner<Cursor<Vec<u8>>, ExecutorError> for Runner {}
65
66#[async_trait]
67impl asimov_patterns::Execute<Cursor<Vec<u8>>, ExecutorError> for Runner {
68 async fn execute(&mut self) -> RunnerResult {
69 self.execute().await
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use asimov_patterns::Execute;
77
78 #[tokio::test]
79 async fn test_execute() {
80 }
82}