asimov_runner/
fetcher.rs

1// This is free and unencumbered software released into the public domain.
2
3use crate::{Runner, RunnerError};
4use async_trait::async_trait;
5use std::{ffi::OsStr, io::Cursor, process::Stdio};
6
7pub use asimov_patterns::FetcherOptions;
8
9pub type FetcherResult = std::result::Result<Cursor<Vec<u8>>, RunnerError>;
10
11/// Network protocol fetcher. Consumes a URL input, produces some output.
12#[derive(Debug)]
13#[allow(unused)]
14pub struct Fetcher {
15    runner: Runner,
16    options: FetcherOptions,
17}
18
19impl Fetcher {
20    pub fn new(program: impl AsRef<OsStr>, options: FetcherOptions) -> Self {
21        let mut runner = Runner::new(program);
22
23        runner
24            .command()
25            .arg(&options.input_url)
26            .stdin(Stdio::null())
27            .stdout(Stdio::piped())
28            .stderr(Stdio::piped());
29
30        Self { runner, options }
31    }
32}
33
34impl asimov_patterns::Fetcher<Cursor<Vec<u8>>, RunnerError> for Fetcher {}
35
36#[async_trait]
37impl asimov_patterns::Execute<Cursor<Vec<u8>>, RunnerError> for Fetcher {
38    async fn execute(&mut self) -> FetcherResult {
39        let stdout = self.runner.execute().await?;
40        Ok(stdout)
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47    use asimov_patterns::Execute;
48
49    #[tokio::test]
50    async fn test_execute() {
51        let mut runner = Fetcher::new(
52            "curl",
53            FetcherOptions {
54                input_url: "https://www.google.com/robots.txt".to_string(),
55            },
56        );
57        let result = runner.execute().await;
58        assert!(result.is_ok());
59    }
60}