Skip to main content

agent_can/cli/
mod.rs

1pub mod args;
2pub mod commands;
3pub mod error;
4pub mod output;
5
6use crate::cli::args::{CliArgs, Command};
7use crate::cli::commands::{daemon_config, to_request};
8use crate::cli::error::CliError;
9use crate::connection::{bootstrap_and_send_request, send_request};
10use crate::daemon::lifecycle;
11use crate::name::validate_bus_name;
12use crate::protocol::Request;
13use std::process::ExitCode;
14use uuid::Uuid;
15
16pub async fn run_with_args(args: CliArgs) -> ExitCode {
17    match run_inner(args).await {
18        Ok(code) => code,
19        Err(err) => {
20            eprintln!("{err}");
21            ExitCode::from(1)
22        }
23    }
24}
25
26async fn run_inner(args: CliArgs) -> Result<ExitCode, CliError> {
27    validate_bus_name(&args.bus).map_err(CliError::CommandFailed)?;
28    let Some(command) = args.command.as_ref() else {
29        return Err(CliError::MissingCommand);
30    };
31
32    match command {
33        Command::Open(_) => {
34            let config = daemon_config(&args)?;
35            let response = bootstrap_and_send_request(
36                &args.bus,
37                &config,
38                &Request {
39                    id: Uuid::new_v4(),
40                    action: crate::protocol::RequestAction::Status,
41                },
42            )
43            .await
44            .map_err(|err| CliError::CommandFailed(err.to_string()))?;
45            output::print_response(&response, args.json);
46        }
47        Command::Bus(_) => {
48            let buses = lifecycle::list_buses()
49                .await
50                .map_err(|err| CliError::CommandFailed(err.to_string()))?;
51            if args.json {
52                println!(
53                    "{}",
54                    serde_json::to_string_pretty(&buses)
55                        .map_err(|err| CliError::CommandFailed(err.to_string()))?
56                );
57            } else {
58                for bus in buses {
59                    println!(
60                        "bus={} running={} socket={}",
61                        bus.bus,
62                        bus.running,
63                        bus.socket_path.display()
64                    );
65                }
66            }
67        }
68        _ => {
69            let request = to_request(&args)?;
70            let response = send_request(&args.bus, &request)
71                .await
72                .map_err(|err| CliError::CommandFailed(err.to_string()))?;
73            output::print_response(&response, args.json);
74            if matches!(command, Command::Close) && response.success {
75                lifecycle::cleanup_runtime_artifacts(&args.bus);
76            }
77            return if response.success {
78                Ok(ExitCode::SUCCESS)
79            } else {
80                Ok(ExitCode::from(1))
81            };
82        }
83    }
84
85    Ok(ExitCode::SUCCESS)
86}