Skip to main content

yog_command/
lib.rs

1//! Command domain — the context passed to a command handler.
2//!
3//! A mod registers a command by name on the registry; when a player runs
4//! `/<name> <args>`, its handler receives a [`CommandContext`] and may return a
5//! reply string sent back to the source.
6
7/// Details of a command invocation.
8#[derive(Debug, Clone)]
9pub struct CommandContext {
10    /// Command name that was run, without the leading slash.
11    pub name: String,
12    /// Raw argument string after the command name (empty if none).
13    pub args: String,
14    /// Name of the player (or console) that ran the command.
15    pub source: String,
16    /// UUID of the executing entity (empty if run from the console).
17    pub uuid: String,
18}
19
20impl CommandContext {
21    /// Arguments split on whitespace — for plain (untyped) commands.
22    pub fn arg_list(&self) -> Vec<&str> {
23        self.args.split_whitespace().collect()
24    }
25
26    // ── typed-command helpers ─────────────────────────────────────────────────
27    //
28    // Typed commands (registered with `Registry::on_typed_command`) receive
29    // tab-separated argument values.  Use these helpers to extract them.
30
31    /// Arguments split on `\t` — for typed commands registered with a schema.
32    pub fn typed_args(&self) -> Vec<&str> {
33        if self.args.is_empty() { vec![] } else { self.args.split('\t').collect() }
34    }
35
36    /// The raw string of typed argument at `idx`, or `None` if out of range.
37    pub fn arg_str(&self, idx: usize) -> Option<&str> {
38        if self.args.is_empty() { return None; }
39        self.args.split('\t').nth(idx)
40    }
41
42    /// Typed argument `idx` parsed as `i32`, or `None`.
43    pub fn arg_int(&self, idx: usize) -> Option<i32> {
44        self.arg_str(idx)?.parse().ok()
45    }
46
47    /// Typed argument `idx` parsed as `f32`, or `None`.
48    pub fn arg_float(&self, idx: usize) -> Option<f32> {
49        self.arg_str(idx)?.parse().ok()
50    }
51
52    /// Typed argument `idx` as a player name, or `None`.
53    pub fn arg_player(&self, idx: usize) -> Option<&str> {
54        self.arg_str(idx)
55    }
56
57    /// Typed argument `idx` as a block position (`"x,y,z"`), or `None`.
58    pub fn arg_blockpos(&self, idx: usize) -> Option<(i32, i32, i32)> {
59        let s = self.arg_str(idx)?;
60        let mut it = s.split(',');
61        let x = it.next()?.parse().ok()?;
62        let y = it.next()?.parse().ok()?;
63        let z = it.next()?.parse().ok()?;
64        Some((x, y, z))
65    }
66}