Skip to main content

slash_lib/builtins/
echo.rs

1use slash_lang::parser::ast::Arg;
2
3use crate::command::{MethodDef, SlashCommand};
4use crate::executor::{CommandOutput, ExecutionError, PipeValue};
5
6/// `/echo` — produce text output.
7///
8/// `/echo(hello world)` — primary arg as output.
9/// `/echo.text(hello world)` — `.text()` method as output.
10/// `/echo` (with piped input) — pass-through.
11pub struct Echo;
12
13impl SlashCommand for Echo {
14    fn name(&self) -> &str {
15        "echo"
16    }
17
18    fn methods(&self) -> &[MethodDef] {
19        static METHODS: [MethodDef; 1] = [MethodDef::with_value("text")];
20        &METHODS
21    }
22
23    fn execute(
24        &self,
25        primary: Option<&str>,
26        args: &[Arg],
27        input: Option<&PipeValue>,
28    ) -> Result<CommandOutput, ExecutionError> {
29        // Primary arg takes precedence.
30        if let Some(text) = primary {
31            let mut out = text.to_string();
32            out.push('\n');
33            return Ok(CommandOutput {
34                stdout: Some(out.into_bytes()),
35                stderr: None,
36                success: true,
37            });
38        }
39
40        // Collect all .text() values.
41        let texts: Vec<&str> = args
42            .iter()
43            .filter(|a| a.name == "text")
44            .filter_map(|a| a.value.as_deref())
45            .collect();
46
47        if !texts.is_empty() {
48            let mut out = texts.join(" ");
49            out.push('\n');
50            return Ok(CommandOutput {
51                stdout: Some(out.into_bytes()),
52                stderr: None,
53                success: true,
54            });
55        }
56
57        // Pass-through piped input.
58        let output = match input {
59            Some(PipeValue::Bytes(b)) => Some(b.clone()),
60            Some(PipeValue::Context(ctx)) => Some(ctx.to_json().into_bytes()),
61            None => None,
62        };
63
64        Ok(CommandOutput {
65            stdout: output,
66            stderr: None,
67            success: true,
68        })
69    }
70}