asimov_cli/commands/
fetch.rs

1// This is free and unencumbered software released into the public domain.
2
3use crate::{
4    StandardOptions,
5    SysexitsError::{self, *},
6    commands::External,
7    shared::{build_resolver, normalize_url},
8};
9use color_print::ceprintln;
10use miette::Result;
11
12pub fn fetch(
13    urls: &Vec<String>,
14    module: Option<&str>,
15    flags: &StandardOptions,
16) -> Result<(), SysexitsError> {
17    let resolver = build_resolver("fetcher").map_err(|e| {
18        ceprintln!("<s,r>error:</> failed to build a resolver: {e}");
19        EX_UNAVAILABLE
20    })?;
21
22    for url in urls {
23        if flags.verbose > 1 {
24            ceprintln!("<s><c>»</></> Fetching `{}`...", url);
25        }
26
27        let url = normalize_url(url);
28
29        let modules = resolver.resolve(&url)?;
30
31        let module = if let Some(want) = module {
32            modules.iter().find(|m| m.name == want).ok_or_else(|| {
33                ceprintln!("<s,r>error:</> failed to find a module named `{want}` that supports fetching the URL: `{url}`");
34                EX_SOFTWARE
35            })?
36        } else {
37            modules.first().ok_or_else(|| {
38                ceprintln!("<s,r>error:</> failed to find a module to fetch the URL: `{url}`");
39                EX_SOFTWARE
40            })?
41        };
42
43        let subcommand = format!("{}-fetcher", module.name);
44
45        let cmd = External {
46            is_debug: flags.debug,
47            pipe_output: false,
48        };
49
50        let code = cmd
51            .execute(&subcommand, &[url.to_owned()])
52            .map(|result| result.code)?;
53        if code.is_failure() {
54            return Err(code);
55        }
56
57        if flags.verbose > 0 {
58            ceprintln!("<s><g>✓</></> Fetched `{}`.", url);
59        }
60    }
61
62    Ok(())
63}