theater_cli/commands/
list.rs

1use clap::Parser;
2use std::net::SocketAddr;
3use tracing::debug;
4
5use crate::client::cli_wrapper;
6use crate::error::CliResult;
7use crate::output::formatters::ActorList;
8use crate::CommandContext;
9
10#[derive(Debug, Parser)]
11pub struct ListArgs {
12    /// Address of the theater server
13    #[arg(short, long, default_value = "127.0.0.1:9000")]
14    pub address: SocketAddr,
15}
16
17/// Execute the list command asynchronously using theater-client
18pub async fn execute_async(args: &ListArgs, ctx: &CommandContext) -> CliResult<()> {
19    debug!("Listing actors using theater-client");
20    debug!("Connecting to server at: {}", args.address);
21
22    // Use the CLI wrapper - all the timeout/retry logic is handled internally
23    let actors = cli_wrapper::list_actors(args.address, &ctx.config).await?;
24
25    // Create formatted output
26    let actor_list = ActorList {
27        actors: actors
28            .into_iter()
29            .map(|(id, name)| (id.to_string(), name))
30            .collect(),
31    };
32
33    // Output using the configured format
34    let format = if ctx.json { Some("json") } else { None };
35    ctx.output.output(&actor_list, format)?;
36
37    Ok(())
38}
39
40// Keep the legacy function for backward compatibility
41pub fn execute(args: &ListArgs, verbose: bool, json: bool) -> anyhow::Result<()> {
42    let runtime = tokio::runtime::Runtime::new()?;
43    runtime.block_on(async {
44        let config = crate::config::Config::load().unwrap_or_default();
45        let output = crate::output::OutputManager::new(config.output.clone());
46
47        let ctx = CommandContext {
48            config,
49            output,
50            verbose,
51            json,
52        };
53
54        execute_async(args, &ctx).await.map_err(Into::into)
55    })
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61    use crate::config::Config;
62    use crate::output::OutputManager;
63
64    #[tokio::test]
65    async fn test_list_command_structure() {
66        let args = ListArgs {
67            address: "127.0.0.1:9000".parse().unwrap(),
68        };
69        let config = Config::default();
70        let output = OutputManager::new(config.output.clone());
71
72        let ctx = CommandContext {
73            config,
74            output,
75            verbose: false,
76            json: false,
77        };
78
79        // This would fail without a server, but tests the structure
80        let result = execute_async(&args, &ctx).await;
81        assert!(result.is_err()); // Expected to fail without server
82    }
83}