Skip to main content

slash_lib/
command.rs

1use slash_lang::parser::ast::Arg;
2
3use crate::executor::{CommandOutput, ExecutionError, PipeValue};
4
5/// Describes a single builder-chain method that a command accepts.
6///
7/// Used by the registry to validate `.method()` calls before dispatch.
8#[derive(Debug, Clone, PartialEq)]
9pub struct MethodDef {
10    /// The method name (e.g. `"text"`, `"level"`, `"append"`).
11    pub name: &'static str,
12    /// Whether this method requires a value: `.method(value)` vs `.flag`.
13    pub takes_value: bool,
14}
15
16impl MethodDef {
17    pub const fn flag(name: &'static str) -> Self {
18        Self {
19            name,
20            takes_value: false,
21        }
22    }
23
24    pub const fn with_value(name: &'static str) -> Self {
25        Self {
26            name,
27            takes_value: true,
28        }
29    }
30}
31
32/// Port: a self-contained tool that knows its own methods.
33///
34/// Each implementor is a builtin command (e.g. `/read`, `/exec`, `/find`).
35/// The registry holds these as `Box<dyn SlashCommand>` and dispatches by name.
36pub trait SlashCommand: Send + Sync {
37    /// The command's registered name (e.g. `"read"`, `"exec"`).
38    fn name(&self) -> &str;
39
40    /// The methods this command accepts.
41    ///
42    /// The registry validates all `.method()` args against this list before
43    /// calling [`execute`](Self::execute). Unknown methods are rejected with
44    /// a clear error message.
45    fn methods(&self) -> &[MethodDef];
46
47    /// Execute the command.
48    ///
49    /// - `primary` — the value from `/cmd(value)` syntax, if present.
50    /// - `args` — builder-chain methods, already validated against [`methods`](Self::methods).
51    /// - `input` — piped data from the previous command, if any.
52    fn execute(
53        &self,
54        primary: Option<&str>,
55        args: &[Arg],
56        input: Option<&PipeValue>,
57    ) -> Result<CommandOutput, ExecutionError>;
58}