opcda_bridge_client/
lib.rs1pub mod cli;
2pub mod commands;
3pub mod config;
4pub mod output;
5
6#[cfg(test)]
7mod test_support;
8
9use std::process::ExitCode;
10
11pub async fn run() -> ExitCode {
18 use clap::Parser;
19 run_with_cli(cli::Cli::parse()).await
20}
21
22async fn run_with_cli(cli: cli::Cli) -> ExitCode {
32 let cli_format = output::resolve_from_cli(&cli);
33 match config::load_config(cli.config.as_deref()) {
34 Err(e) => fail(&e, cli_format.unwrap_or(output::OutputFormat::Table)),
35 Ok(config) => {
36 let format = config::resolve_output(cli_format, &config);
37 match cli::run_command(cli, &config, format).await {
38 Ok(()) => ExitCode::SUCCESS,
39 Err(e) => fail(&e, format),
40 }
41 }
42 }
43}
44
45fn fail(err: &anyhow::Error, format: output::OutputFormat) -> ExitCode {
48 eprintln!("{}", output::format_error(err, format));
49 ExitCode::FAILURE
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55 use crate::cli::{Cli, Commands};
56 use crate::test_support::{MockBridgeService, start_mock_server};
57 use std::path::PathBuf;
58
59 fn base_cli(command: Commands) -> Cli {
60 Cli {
61 host: None,
62 config: None,
63 output: None,
64 json: false,
65 command,
66 }
67 }
68
69 #[tokio::test]
70 async fn test_run_with_cli_success_is_exit_success() {
71 let host = start_mock_server(MockBridgeService::default()).await;
72 let mut cli = base_cli(Commands::Servers);
73 cli.host = Some(host);
74 assert_eq!(run_with_cli(cli).await, ExitCode::SUCCESS);
75 }
76
77 #[tokio::test]
78 async fn test_run_with_cli_command_error_is_exit_failure() {
79 let cli = base_cli(Commands::Browse {
82 server: None,
83 flat: false,
84 path: String::new(),
85 max_tags: None,
86 });
87 assert_eq!(run_with_cli(cli).await, ExitCode::FAILURE);
88 }
89
90 #[tokio::test]
91 async fn test_run_with_cli_config_load_failure_is_exit_failure() {
92 let mut cli = base_cli(Commands::Servers);
95 cli.config = Some(PathBuf::from("/nonexistent/opcda-bridge-client.toml"));
96 assert_eq!(run_with_cli(cli).await, ExitCode::FAILURE);
97 }
98
99 #[tokio::test]
100 async fn test_run_with_cli_config_load_failure_uses_cli_only_format() {
101 let mut cli = base_cli(Commands::Servers);
106 cli.config = Some(PathBuf::from("/nonexistent/opcda-bridge-client.toml"));
107 cli.json = true;
108 assert_eq!(run_with_cli(cli).await, ExitCode::FAILURE);
109 }
110
111 #[test]
112 fn test_fail_returns_exit_failure() {
113 let err = anyhow::anyhow!("boom");
114 assert_eq!(fail(&err, output::OutputFormat::Table), ExitCode::FAILURE);
115 assert_eq!(fail(&err, output::OutputFormat::Json), ExitCode::FAILURE);
116 }
117}