Skip to main content

via/
app.rs

1use std::ffi::OsString;
2use std::process::ExitCode;
3
4use crate::cli::{print_help, Cli, Command};
5use crate::config::Config;
6use crate::error::ViaError;
7use crate::executor;
8use crate::providers::ProviderRegistry;
9
10pub fn run(args: impl IntoIterator<Item = OsString>) -> ExitCode {
11    crate::tls::install_crypto_provider();
12
13    match try_run(args) {
14        Ok(code) => code,
15        Err(ViaError::Clap(error)) => {
16            let exit_code = if error.use_stderr() { 2 } else { 0 };
17            if error.use_stderr() {
18                eprint!("{error}");
19            } else {
20                print!("{error}");
21            }
22            ExitCode::from(exit_code)
23        }
24        Err(error) => {
25            eprintln!("error: {error}");
26            ExitCode::from(error.exit_code())
27        }
28    }
29}
30
31fn try_run(args: impl IntoIterator<Item = OsString>) -> Result<ExitCode, ViaError> {
32    let cli = Cli::parse(args)?;
33
34    match cli.command {
35        Command::Help => {
36            print_help();
37            Ok(ExitCode::SUCCESS)
38        }
39        Command::Capabilities { json } => {
40            let config = Config::load(cli.config_path.as_deref())?;
41            crate::capabilities::print(&config, json)?;
42            Ok(ExitCode::SUCCESS)
43        }
44        Command::Config(command) => {
45            crate::config_command::run(cli.config_path.as_deref(), command)?;
46            Ok(ExitCode::SUCCESS)
47        }
48        Command::SkillPrint => {
49            let config = Config::load(cli.config_path.as_deref())?;
50            crate::skill::print(&config);
51            Ok(ExitCode::SUCCESS)
52        }
53        Command::Invoke {
54            service,
55            capability,
56            args,
57        } => {
58            let config = Config::load(cli.config_path.as_deref())?;
59            let providers = ProviderRegistry::from_config(&config)?;
60            executor::invoke(&config, &providers, &service, &capability, args)?;
61            Ok(ExitCode::SUCCESS)
62        }
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn capabilities_command_returns_success() {
72        let code = try_run([
73            OsString::from("via"),
74            OsString::from("--config"),
75            OsString::from("examples/github.toml"),
76            OsString::from("capabilities"),
77        ])
78        .unwrap();
79
80        assert_eq!(code, ExitCode::SUCCESS);
81    }
82}