1mod fit;
8
9pub use fit::{Fit, GREEDY};
10
11#[derive(Debug, Clone)]
13pub struct CommandContext {
14 pub name: String,
16 pub args: Vec<String>,
18 pub source: String,
20 pub uuid: String,
22 pub dimension: String,
24}
25
26impl CommandContext {
27 pub fn arg_str(&self, idx: usize) -> Option<&str> {
29 self.args.get(idx).map(String::as_str)
30 }
31
32 pub fn arg_int(&self, idx: usize) -> Option<i32> {
34 self.arg_str(idx)?.parse().ok()
35 }
36
37 pub fn arg_float(&self, idx: usize) -> Option<f32> {
39 self.arg_str(idx)?.parse().ok()
40 }
41
42 pub fn arg_player(&self, idx: usize) -> Option<&str> {
44 self.arg_str(idx)
45 }
46
47 pub fn arg_blockpos(&self, idx: usize) -> Option<(i32, i32, i32)> {
49 let s = self.arg_str(idx)?;
50 let mut it = s.split(',');
51 let x = it.next()?.parse().ok()?;
52 let y = it.next()?.parse().ok()?;
53 let z = it.next()?.parse().ok()?;
54 Some((x, y, z))
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 fn ctx(args: &[&str]) -> CommandContext {
63 CommandContext {
64 name: "hex".into(),
65 args: args.iter().map(|a| (*a).to_owned()).collect(),
66 source: "Dev".into(),
67 uuid: String::new(),
68 dimension: String::new(),
69 }
70 }
71
72 #[test]
73 fn typed_arguments() {
74 let t = ctx(&["5", "2.5", "Steve", "1,-2,3"]);
75 assert_eq!(t.arg_int(0), Some(5));
76 assert_eq!(t.arg_float(1), Some(2.5));
77 assert_eq!(t.arg_player(2), Some("Steve"));
78 assert_eq!(t.arg_blockpos(3), Some((1, -2, 3)));
79 assert_eq!(t.arg_int(2), None, "not a number");
80 assert_eq!(t.arg_str(9), None);
81 assert_eq!(ctx(&[]).arg_str(0), None);
82 assert_eq!(ctx(&["1,2"]).arg_blockpos(0), None);
83 }
84}