Skip to main content

asimov_runner/programs/
runner.rs

1// This is free and unencumbered software released into the public domain.
2
3use 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
15/// See: https://asimov-specs.github.io/program-patterns/#runner
16pub type RunnerResult = std::result::Result<Cursor<Vec<u8>>, ExecutorError>; // TODO
17
18/// See: https://asimov-specs.github.io/program-patterns/#runner
19#[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        // TODO
81    }
82}