Add decorator

This commit is contained in:
2026-02-19 18:23:20 +08:00
parent ba08f8b9f7
commit 7933d76a92
17 changed files with 499 additions and 86 deletions

View File

@@ -5,6 +5,8 @@ edition = "2024"
[dependencies]
serde_json = "1.0.149"
quartz_nbt = { version = "0.2.9", features = ["serde"] }
serde.workspace = true
color-eyre.workspace = true
log.workspace = true

View File

@@ -1,3 +1,6 @@
use std::error::Error;
use std::fmt::{Display};
#[derive(Debug, Clone)]
pub enum CommandError {
EmptyCommand,
@@ -19,7 +22,7 @@ pub enum CommandError {
},
}
impl std::fmt::Display for CommandError {
impl Display for CommandError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::EmptyCommand => write!(f, "Empty command"),
@@ -45,4 +48,4 @@ impl std::fmt::Display for CommandError {
}
}
impl std::error::Error for CommandError {}
impl Error for CommandError {}

View File

@@ -17,13 +17,10 @@ impl MinecraftCommandValidator {
pub fn validate(&self, command: &str) -> Result<ValidationResult, CommandError> {
let tokens = self.tokenize(command);
if tokens.is_empty() {
return Err(CommandError::EmptyCommand);
}
let result = self.validate_tokens(&tokens, &self.root, 0, Vec::new())?;
Ok(result)
}
@@ -87,20 +84,7 @@ impl MinecraftCommandValidator {
let current_token = &tokens[index];
let children = node.children();
if children.is_empty() && node.redirects().is_empty() {
return if node.is_executable() {
Err(CommandError::TooManyArguments {
path: path.join(" "),
})
} else {
Err(CommandError::IncompleteCommand {
path: path.join(" "),
suggestions: self.get_suggestions_from_node(node),
})
}
}
if !node.redirects().is_empty() {
let nodes = self.get_redirects(&node.redirects());
for node in nodes {
@@ -113,6 +97,19 @@ impl MinecraftCommandValidator {
to: node.redirects().to_vec(),
})
}
if children.is_empty() {
return if node.is_executable() {
Err(CommandError::TooManyArguments {
path: path.join(" "),
})
} else {
Err(CommandError::IncompleteCommand {
path: path.join(" "),
suggestions: self.get_suggestions_from_node(node),
})
}
}
for child in children {
if let CommandNode::Literal { name, .. } = child && name == current_token {
@@ -210,8 +207,15 @@ impl MinecraftCommandValidator {
}
}
ParserType::String { .. } => Ok(()),
ParserType::Message | ParserType::Component => Ok(()),
_ => Ok(()),
ParserType::Message => Ok(()),
ParserType::Component => match quartz_nbt::snbt::parse(value) {
Ok(_) => Ok(()),
Err(e) => Err(format!("Invalid component: {}", e)),
},
_ => {
log::warn!("Unknown parser type: {:?}, for '{}'", parser_type, value);
Ok(())
}
}
}

View File

@@ -0,0 +1,9 @@
pub struct PackMcMeta {
min_format: [u8; 2],
max_format: [u8; 2],
support_version: [u8; 2]
}
pub struct FunctionTag {
value: Vec<String>
}

View File

@@ -1,8 +1,10 @@
mod enums;
mod parser;
mod mcmeta;
pub use enums::*;
pub use parser::*;
pub use mcmeta::*;
use serde::{Deserialize, Serialize};