Skip to main content

asimov_runner/programs/
adapter.rs

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