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 /// Dimension the source is in, empty for console-run commands (no world).
19 pub dimension: String,
20}
21
22impl CommandContext {
23 /// Arguments split on whitespace — for plain (untyped) commands.
24 pub fn arg_list(&self) -> Vec<&str> {
25 self.args.split_whitespace().collect()
26 }
27
28 // ── typed-command helpers ─────────────────────────────────────────────────
29 //
30 // Typed commands (registered with `Registry::on_typed_command`) receive
31 // tab-separated argument values. Use these helpers to extract them.
32
33 /// Arguments split on `\t` — for typed commands registered with a schema.
34 pub fn typed_args(&self) -> Vec<&str> {
35 if self.args.is_empty() {
36 vec![]
37 } else {
38 self.args.split('\t').collect()
39 }
40 }
41
42 /// The raw string of typed argument at `idx`, or `None` if out of range.
43 pub fn arg_str(&self, idx: usize) -> Option<&str> {
44 if self.args.is_empty() {
45 return None;
46 }
47 self.args.split('\t').nth(idx)
48 }
49
50 /// Typed argument `idx` parsed as `i32`, or `None`.
51 pub fn arg_int(&self, idx: usize) -> Option<i32> {
52 self.arg_str(idx)?.parse().ok()
53 }
54
55 /// Typed argument `idx` parsed as `f32`, or `None`.
56 pub fn arg_float(&self, idx: usize) -> Option<f32> {
57 self.arg_str(idx)?.parse().ok()
58 }
59
60 /// Typed argument `idx` as a player name, or `None`.
61 pub fn arg_player(&self, idx: usize) -> Option<&str> {
62 self.arg_str(idx)
63 }
64
65 /// Typed argument `idx` as a block position (`"x,y,z"`), or `None`.
66 pub fn arg_blockpos(&self, idx: usize) -> Option<(i32, i32, i32)> {
67 let s = self.arg_str(idx)?;
68 let mut it = s.split(',');
69 let x = it.next()?.parse().ok()?;
70 let y = it.next()?.parse().ok()?;
71 let z = it.next()?.parse().ok()?;
72 Some((x, y, z))
73 }
74}