theater_cli/commands/
state.rs1use clap::Parser;
2use std::net::SocketAddr;
3use std::str::FromStr;
4use tracing::debug;
5
6use crate::error::{CliError, CliResult};
7use crate::output::formatters::ActorState;
8use crate::CommandContext;
9use theater::id::TheaterId;
10
11#[derive(Debug, Parser)]
12pub struct StateArgs {
13 #[arg(required = true)]
15 pub actor_id: String,
16
17 #[arg(short, long, default_value = "127.0.0.1:9000")]
19 pub address: SocketAddr,
20
21 #[arg(short, long, default_value = "pretty")]
23 pub format: String,
24}
25
26pub async fn execute_async(args: &StateArgs, ctx: &CommandContext) -> CliResult<()> {
28 debug!("Getting state for actor: {}", args.actor_id);
29 debug!("Connecting to server at: {}", args.address);
30
31 let actor_id = TheaterId::from_str(&args.actor_id).map_err(|_| CliError::InvalidInput {
33 field: "actor_id".to_string(),
34 value: args.actor_id.clone(),
35 suggestion: "Provide a valid actor ID in the correct format".to_string(),
36 })?;
37
38 let client = ctx.create_client();
40 client
41 .connect()
42 .await
43 .map_err(|e| CliError::connection_failed(args.address, e))?;
44
45 let state = client
47 .get_actor_state(&actor_id.to_string())
48 .await
49 .map_err(|e| CliError::ServerError {
50 message: format!("Failed to get actor state: {}", e),
51 })?;
52
53 let actor_state = ActorState {
55 actor_id: actor_id.to_string(),
56 state,
57 };
58
59 let format = if ctx.json {
61 Some("json")
62 } else {
63 Some(args.format.as_str())
64 };
65 ctx.output.output(&actor_state, format)?;
66
67 Ok(())
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use crate::config::Config;
74 use crate::output::OutputManager;
75
76 #[tokio::test]
77 async fn test_state_command_invalid_actor_id() {
78 let args = StateArgs {
79 actor_id: "invalid-id".to_string(),
80 address: "127.0.0.1:9000".parse().unwrap(),
81 format: "pretty".to_string(),
82 };
83 let config = Config::default();
84 let output = OutputManager::new(config.output.clone());
85
86 let ctx = CommandContext {
87 config,
88 output,
89 verbose: false,
90 json: false,
91 };
92
93 let result = execute_async(&args, &ctx).await;
94 assert!(result.is_err());
95 if let Err(CliError::InvalidInput { field, .. }) = result {
96 assert_eq!(field, "actor_id");
97 } else {
98 panic!("Expected InvalidInput error");
99 }
100 }
101}