add command usage hint after syntax error
This commit is contained in:
parent
943f8fcd4c
commit
40b2fdc45f
@ -19,7 +19,7 @@ pub(crate) struct CommandDispatcher<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl <'a> 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 mut parts = cmd.split_ascii_whitespace();
|
||||||
let key = parts.next().ok_or("Empty Command")?;
|
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()) {
|
match Self::try_path(src, path, tree, raw_args.clone()) {
|
||||||
Err(InvalidConsumptionError(s)) => {
|
Err(InvalidConsumptionError(s)) => {
|
||||||
println!("Error while parsing command \"{cmd}\": {s:?} was consumed, but couldn't be parsed");
|
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) => {
|
Err(InvalidRequirementError) => {
|
||||||
println!("Error while parsing command \"{cmd}\": a requirement that was expected was not met.");
|
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) => {
|
Ok(fitting_path) => {
|
||||||
if fitting_path { return Ok(()) }
|
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> {
|
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::client::Client;
|
||||||
use crate::commands::dispatcher::CommandDispatcher;
|
use crate::commands::dispatcher::CommandDispatcher;
|
||||||
|
use crate::server::Server;
|
||||||
|
|
||||||
mod cmd_gamemode;
|
mod cmd_gamemode;
|
||||||
mod cmd_pumpkin;
|
mod cmd_pumpkin;
|
||||||
mod cmd_stop;
|
mod cmd_stop;
|
||||||
@ -11,6 +13,7 @@ mod tree;
|
|||||||
mod tree_builder;
|
mod tree_builder;
|
||||||
mod dispatcher;
|
mod dispatcher;
|
||||||
mod arg_player;
|
mod arg_player;
|
||||||
|
mod cmd_teleport;
|
||||||
|
|
||||||
pub enum CommandSender<'a> {
|
pub enum CommandSender<'a> {
|
||||||
Rcon(&'a mut Vec<String>),
|
Rcon(&'a mut Vec<String>),
|
||||||
|
|||||||
@ -50,6 +50,49 @@ impl <'a> CommandTree<'a> {
|
|||||||
todo,
|
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> {
|
struct TraverseAllPathsIter<'a> {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user