1use crate::config::{CommandConfig, Config};
2use crate::error::ViaError;
3use crate::providers::ProviderRegistry;
4
5mod delegated;
6mod rest;
7
8pub fn invoke(
9 config: &Config,
10 providers: &ProviderRegistry,
11 service_name: &str,
12 capability_name: &str,
13 args: Vec<String>,
14) -> Result<(), ViaError> {
15 let service = config
16 .services
17 .get(service_name)
18 .ok_or_else(|| ViaError::UnknownService(service_name.to_owned()))?;
19 let command =
20 service
21 .commands
22 .get(capability_name)
23 .ok_or_else(|| ViaError::UnknownCapability {
24 service: service_name.to_owned(),
25 capability: capability_name.to_owned(),
26 })?;
27 let provider = providers.get(&service.provider)?;
28
29 match command {
30 CommandConfig::Rest(rest) => rest::execute(service_name, service, rest, provider, args),
31 CommandConfig::Delegated(delegated) => {
32 delegated::execute(service_name, service, delegated, provider, args)
33 }
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 fn config() -> Config {
42 Config::from_toml_str(
43 r#"
44version = 1
45
46[providers.onepassword]
47type = "1password"
48
49[services.github]
50provider = "onepassword"
51
52[services.github.secrets]
53token = "op://Private/GitHub/token"
54
55[services.github.commands.api]
56mode = "rest"
57base_url = "https://api.github.com"
58"#,
59 )
60 .unwrap()
61 }
62
63 #[test]
64 fn invoke_rejects_unknown_service() {
65 let config = config();
66 let providers = ProviderRegistry::from_config(&config).unwrap();
67 let error = invoke(&config, &providers, "missing", "api", Vec::new()).unwrap_err();
68
69 assert!(matches!(error, ViaError::UnknownService(service) if service == "missing"));
70 }
71
72 #[test]
73 fn invoke_rejects_unknown_capability() {
74 let config = config();
75 let providers = ProviderRegistry::from_config(&config).unwrap();
76 let error = invoke(&config, &providers, "github", "missing", Vec::new()).unwrap_err();
77
78 assert!(matches!(
79 error,
80 ViaError::UnknownCapability {
81 service,
82 capability
83 } if service == "github" && capability == "missing"
84 ));
85 }
86}