Skip to main content

asimov_runner/programs/
reasoner.rs

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