agent_core/tui/commands/
custom.rs

1//! Custom command helper for closure-based commands.
2
3use super::context::CommandContext;
4use super::result::CommandResult;
5use super::traits::SlashCommand;
6
7/// A simple custom command using a closure.
8///
9/// Use this for commands that don't need internal state.
10/// For stateful commands, implement [`SlashCommand`] directly.
11///
12/// # Example
13///
14/// ```ignore
15/// use agent_core::tui::commands::{CustomCommand, CommandResult};
16///
17/// let cmd = CustomCommand::new(
18///     "greet",
19///     "Say hello to someone",
20///     |args, ctx| {
21///         let name = if args.is_empty() { "World" } else { args };
22///         CommandResult::Message(format!("Hello, {}!", name))
23///     },
24/// );
25/// ```
26pub struct CustomCommand {
27    name: String,
28    description: String,
29    handler: Box<dyn Fn(&str, &mut CommandContext) -> CommandResult + Send + Sync>,
30}
31
32impl CustomCommand {
33    /// Create a new custom command.
34    ///
35    /// # Arguments
36    /// * `name` - Command name without the leading slash
37    /// * `description` - Short description shown in the popup
38    /// * `handler` - Closure that executes the command
39    pub fn new<F>(name: impl Into<String>, description: impl Into<String>, handler: F) -> Self
40    where
41        F: Fn(&str, &mut CommandContext) -> CommandResult + Send + Sync + 'static,
42    {
43        Self {
44            name: name.into(),
45            description: description.into(),
46            handler: Box::new(handler),
47        }
48    }
49}
50
51impl SlashCommand for CustomCommand {
52    fn name(&self) -> &str {
53        &self.name
54    }
55
56    fn description(&self) -> &str {
57        &self.description
58    }
59
60    fn execute(&self, args: &str, ctx: &mut CommandContext) -> CommandResult {
61        (self.handler)(args, ctx)
62    }
63}