Skip to main content

asimov_runner/programs/
emitter.rs

1// This is free and unencumbered software released into the public domain.
2
3use crate::{Executor, ExecutorError, GraphOutput, Input, NoInput, 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::EmitterOptions;
14
15/// See: https://asimov-specs.github.io/program-patterns/#emitter
16pub type EmitterResult = std::result::Result<Cursor<Vec<u8>>, ExecutorError>; // TODO
17
18/// See: https://asimov-specs.github.io/program-patterns/#emitter
19#[allow(unused)]
20#[derive(Debug)]
21pub struct Emitter {
22    executor: Executor,
23    options: EmitterOptions,
24    input: NoInput,
25    output: GraphOutput,
26}
27
28impl Emitter {
29    pub fn new(program: impl AsRef<OsStr>, output: Output, options: EmitterOptions) -> Self {
30        let mut executor = Executor::new(program);
31        executor
32            .command()
33            .args(if let Some(ref output) = options.output {
34                vec![format!("--output={}", output)]
35            } else {
36                vec![]
37            })
38            .args(&options.other)
39            .stdin(Stdio::null())
40            .stdout(output.as_stdio())
41            .stderr(Stdio::piped());
42
43        Self {
44            executor,
45            options,
46            input: (),
47            output,
48        }
49    }
50
51    pub async fn execute(&mut self) -> EmitterResult {
52        let stdout = self.executor.execute().await?;
53        Ok(stdout)
54    }
55}
56
57impl asimov_patterns::Emitter<Cursor<Vec<u8>>, ExecutorError> for Emitter {}
58
59#[async_trait]
60impl asimov_patterns::Execute<Cursor<Vec<u8>>, ExecutorError> for Emitter {
61    async fn execute(&mut self) -> EmitterResult {
62        self.execute().await
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use asimov_patterns::Execute;
70
71    #[tokio::test]
72    async fn test_execute() {
73        // TODO
74    }
75}