Skip to main content

asimov_runner/programs/
cataloger.rs

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