mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-31 08:22:33 +00:00
add command usage hint after syntax error
This commit is contained in:
@@ -19,7 +19,7 @@ pub(crate) struct CommandDispatcher<'a> {
|
||||
}
|
||||
|
||||
impl <'a> CommandDispatcher<'a> {
|
||||
pub(crate) fn dispatch(&'a self, src: &mut CommandSender, cmd: &str) -> Result<(), &str> {
|
||||
pub(crate) fn dispatch(&'a self, src: &mut CommandSender, cmd: &str) -> Result<(), String> {
|
||||
|
||||
let mut parts = cmd.split_ascii_whitespace();
|
||||
let key = parts.next().ok_or("Empty Command")?;
|
||||
@@ -31,9 +31,11 @@ impl <'a> CommandDispatcher<'a> {
|
||||
match Self::try_path(src, path, tree, raw_args.clone()) {
|
||||
Err(InvalidConsumptionError(s)) => {
|
||||
println!("Error while parsing command \"{cmd}\": {s:?} was consumed, but couldn't be parsed");
|
||||
return Err("Internal Error (See logs for details)".into())
|
||||
},
|
||||
Err(InvalidRequirementError) => {
|
||||
println!("Error while parsing command \"{cmd}\": a requirement that was expected was not met.");
|
||||
return Err("Internal Error (See logs for details)".into())
|
||||
},
|
||||
Ok(fitting_path) => {
|
||||
if fitting_path { return Ok(()) }
|
||||
@@ -41,7 +43,7 @@ impl <'a> CommandDispatcher<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
Err("Invalid Syntax: ")
|
||||
Err(format!("Invalid Syntax. Usage:{}", tree.paths_formatted(key)))
|
||||
}
|
||||
|
||||
fn try_path(src: &mut CommandSender, path: Vec<usize>, tree: &CommandTree, mut raw_args: RawArgs) -> Result<bool, InvalidTreeError> {
|
||||
|
||||
@@ -4,6 +4,8 @@ use pumpkin_text::TextComponent;
|
||||
|
||||
use crate::client::Client;
|
||||
use crate::commands::dispatcher::CommandDispatcher;
|
||||
use crate::server::Server;
|
||||
|
||||
mod cmd_gamemode;
|
||||
mod cmd_pumpkin;
|
||||
mod cmd_stop;
|
||||
@@ -11,6 +13,7 @@ mod tree;
|
||||
mod tree_builder;
|
||||
mod dispatcher;
|
||||
mod arg_player;
|
||||
mod cmd_teleport;
|
||||
|
||||
pub enum CommandSender<'a> {
|
||||
Rcon(&'a mut Vec<String>),
|
||||
|
||||
@@ -50,6 +50,49 @@ impl <'a> CommandTree<'a> {
|
||||
todo,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn paths_formatted(&'a self, name: &str) -> String {
|
||||
let paths: Vec<Vec<&NodeType>> = self.iter_paths()
|
||||
.map(|path| path.iter().map(|&i| &self.nodes[i].node_type).collect())
|
||||
.collect();
|
||||
|
||||
let len = paths.iter()
|
||||
.map(|path| path.iter()
|
||||
.map(|node| match node {
|
||||
NodeType::ExecuteLeaf { .. } => 0,
|
||||
NodeType::Literal { string } => string.len() + 1,
|
||||
NodeType::Argument { name, .. } => name.len() + 3,
|
||||
NodeType::Require { .. } => 0,
|
||||
})
|
||||
.sum::<usize>() + name.len() + 2
|
||||
)
|
||||
.sum::<usize>();
|
||||
|
||||
let mut s = String::with_capacity(len);
|
||||
|
||||
for path in paths {
|
||||
s.push('\n');
|
||||
s.push('/');
|
||||
s.push_str(name);
|
||||
for node in path {
|
||||
match node {
|
||||
NodeType::Literal { string } => {
|
||||
s.push(' ');
|
||||
s.push_str(string);
|
||||
}
|
||||
NodeType::Argument { name, .. } => {
|
||||
s.push(' ');
|
||||
s.push('<');
|
||||
s.push_str(name);
|
||||
s.push('>');
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
struct TraverseAllPathsIter<'a> {
|
||||
|
||||
Reference in New Issue
Block a user