aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--azalea-brigadier/src/arguments/argument_type.rs12
-rw-r--r--azalea-brigadier/src/arguments/bool_argument_type.rs2
-rw-r--r--azalea-brigadier/src/builder/argument_builder.rs7
-rw-r--r--azalea-brigadier/src/builder/required_argument_builder.rs120
-rw-r--r--azalea-brigadier/src/command_dispatcher.rs2
-rw-r--r--azalea-brigadier/src/context/command_context.rs6
-rw-r--r--azalea-brigadier/src/context/command_context_builder.rs14
-rw-r--r--azalea-brigadier/src/context/parsed_argument.rs6
-rw-r--r--azalea-brigadier/src/tree/argument_command_node.rs11
-rw-r--r--azalea-brigadier/src/tree/command_node.rs11
10 files changed, 160 insertions, 31 deletions
diff --git a/azalea-brigadier/src/arguments/argument_type.rs b/azalea-brigadier/src/arguments/argument_type.rs
index 34d57285..ea453a1a 100644
--- a/azalea-brigadier/src/arguments/argument_type.rs
+++ b/azalea-brigadier/src/arguments/argument_type.rs
@@ -5,7 +5,12 @@ use crate::{
suggestion::{suggestions::Suggestions, suggestions_builder::SuggestionsBuilder},
};
-pub trait ArgumentType {
+pub trait ArgumentResult {}
+
+pub trait ArgumentType<T>
+where
+ T: ArgumentResult,
+{
// T parse(StringReader reader) throws CommandSyntaxException;
// default <S> CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
@@ -16,12 +21,13 @@ pub trait ArgumentType {
// return Collections.emptyList();
// }
- fn parse<T>(reader: &mut StringReader) -> Result<T, CommandSyntaxException>;
+ fn parse(&self, reader: &mut StringReader) -> Result<T, CommandSyntaxException>;
fn list_suggestions<S>(
+ &self,
context: &CommandContext<S>,
builder: &mut SuggestionsBuilder,
) -> Result<Suggestions, CommandSyntaxException>;
- fn get_examples() -> Vec<String>;
+ fn get_examples(&self) -> Vec<String>;
}
diff --git a/azalea-brigadier/src/arguments/bool_argument_type.rs b/azalea-brigadier/src/arguments/bool_argument_type.rs
index f4c03373..74df3331 100644
--- a/azalea-brigadier/src/arguments/bool_argument_type.rs
+++ b/azalea-brigadier/src/arguments/bool_argument_type.rs
@@ -4,7 +4,7 @@ use super::argument_type::ArgumentType;
struct BoolArgumentType {}
-impl ArgumentType for BoolArgumentType {}
+impl ArgumentType<bool> for BoolArgumentType {}
impl BoolArgumentType {
const EXAMPLES: &'static [&'static str] = &["true", "false"];
diff --git a/azalea-brigadier/src/builder/argument_builder.rs b/azalea-brigadier/src/builder/argument_builder.rs
index 8a64a9e4..19706a22 100644
--- a/azalea-brigadier/src/builder/argument_builder.rs
+++ b/azalea-brigadier/src/builder/argument_builder.rs
@@ -10,7 +10,7 @@ where
T: ArgumentBuilder<S, T>,
{
arguments: RootCommandNode<S>,
- command: dyn Command<S>,
+ command: Option<dyn Command<S>>,
requirement: dyn Fn(&S) -> bool,
target: Option<dyn CommandNode<S>>,
modifier: Option<dyn RedirectModifier<S>>,
@@ -18,7 +18,6 @@ where
}
pub trait ArgumentBuilder<S, T> {
- fn this() -> T;
fn build(self) -> dyn CommandNode<S>;
}
@@ -92,11 +91,11 @@ where
Ok(self)
}
- pub fn redirect(&self) -> Option<&dyn CommandNode<S>> {
+ pub fn get_redirect(&self) -> Option<&dyn CommandNode<S>> {
self.target.as_ref()
}
- pub fn redirect_modifier(&self) -> Option<&dyn RedirectModifier<S>> {
+ pub fn get_redirect_modifier(&self) -> Option<&dyn RedirectModifier<S>> {
self.modifier.as_ref()
}
diff --git a/azalea-brigadier/src/builder/required_argument_builder.rs b/azalea-brigadier/src/builder/required_argument_builder.rs
index e69de29b..3ec613c4 100644
--- a/azalea-brigadier/src/builder/required_argument_builder.rs
+++ b/azalea-brigadier/src/builder/required_argument_builder.rs
@@ -0,0 +1,120 @@
+use crate::{
+ arguments::argument_type::ArgumentType,
+ suggestion::suggestion_provider::SuggestionProvider,
+ tree::{argument_command_node::ArgumentCommandNode, command_node::BaseCommandNode},
+};
+
+use super::argument_builder::BaseArgumentBuilder;
+
+// private RequiredArgumentBuilder(final String name, final ArgumentType<T> type) {
+// this.name = name;
+// this.type = type;
+// }
+
+// public static <S, T> RequiredArgumentBuilder<S, T> argument(final String name, final ArgumentType<T> type) {
+// return new RequiredArgumentBuilder<>(name, type);
+// }
+
+// public RequiredArgumentBuilder<S, T> suggests(final SuggestionProvider<S> provider) {
+// this.suggestionsProvider = provider;
+// return getThis();
+// }
+
+// public SuggestionProvider<S> getSuggestionsProvider() {
+// return suggestionsProvider;
+// }
+
+// @Override
+// protected RequiredArgumentBuilder<S, T> getThis() {
+// return this;
+// }
+
+// public ArgumentType<T> getType() {
+// return type;
+// }
+
+// public String getName() {
+// return name;
+// }
+
+// public ArgumentCommandNode<S, T> build() {
+// final ArgumentCommandNode<S, T> result = new ArgumentCommandNode<>(getName(), getType(), getCommand(), getRequirement(), getRedirect(), getRedirectModifier(), isFork(), getSuggestionsProvider());
+
+// for (final CommandNode<S> argument : getArguments()) {
+// result.addChild(argument);
+// }
+
+// return result;
+// }
+
+pub struct RequiredArgumentBuilder<S, T> {
+ // private final String name;
+ // private final ArgumentType<T> type;
+ // private SuggestionProvider<S> suggestionsProvider = null;
+ name: String,
+ type_: dyn ArgumentType<T>,
+ suggestions_provider: Option<dyn SuggestionProvider<S>>,
+
+ pub base: BaseArgumentBuilder<S, T>,
+}
+
+impl<S, T> RequiredArgumentBuilder<S, T> {
+ pub fn new(name: String, type_: dyn ArgumentType<T>) -> Self {
+ Self {
+ name,
+ type_,
+ suggestions_provider: None,
+ base: BaseArgumentBuilder::new(name, type_),
+ }
+ }
+
+ pub fn argument(name: String, type_: dyn ArgumentType<T>) -> Self {
+ Self::new(name, type_)
+ }
+
+ pub fn suggests(mut self, provider: dyn SuggestionProvider<S>) -> Self {
+ self.suggestions_provider = Some(provider);
+ self
+ }
+
+ pub fn suggestions_provider(&self) -> Option<&dyn SuggestionProvider<S>> {
+ self.suggestions_provider.as_ref()
+ }
+
+ pub fn get_type(&self) -> &dyn ArgumentType<T> {
+ &self.type_
+ }
+
+ pub fn name(&self) -> &str {
+ &self.name
+ }
+
+ // final ArgumentCommandNode<S, T> result = new ArgumentCommandNode<>(getName(), getType(), getCommand(), getRequirement(), getRedirect(), getRedirectModifier(), isFork(), getSuggestionsProvider());
+
+ // for (final CommandNode<S> argument : getArguments()) {
+ // result.addChild(argument);
+ // }
+
+ // return result;
+ pub fn build(self) -> ArgumentCommandNode<S, T> {
+ let result = ArgumentCommandNode {
+ name: self.name,
+ type_: &self.type_,
+ base: BaseCommandNode {
+ command: self.base.command,
+ requirement: self.base.requirement,
+ redirect: self.base.redirect,
+ modifier: self.base.modifier,
+ forks: self.base.forks,
+ ..BaseCommandNode::default()
+ },
+ custom_suggestions: self.base.custom_suggestions,
+ };
+
+ for argument in self.base.arguments {
+ result.add_child(argument);
+ }
+
+ result
+ }
+}
diff --git a/azalea-brigadier/src/command_dispatcher.rs b/azalea-brigadier/src/command_dispatcher.rs
index c476a39b..0e9b9036 100644
--- a/azalea-brigadier/src/command_dispatcher.rs
+++ b/azalea-brigadier/src/command_dispatcher.rs
@@ -1,3 +1,5 @@
+use crate::tree::root_command_node::RootCommandNode;
+
/// The core command dispatcher, for registering, parsing, and executing commands.
/// The `S` generic is a custom "source" type, such as a user or originator of a command
pub struct CommandDispatcher<S> {
diff --git a/azalea-brigadier/src/context/command_context.rs b/azalea-brigadier/src/context/command_context.rs
index c6210a88..7a2189d9 100644
--- a/azalea-brigadier/src/context/command_context.rs
+++ b/azalea-brigadier/src/context/command_context.rs
@@ -3,7 +3,9 @@ use super::{
string_range::StringRange,
};
use crate::{
- arguments::argument_type::ArgumentType, command::Command, redirect_modifier::RedirectModifier,
+ arguments::argument_type::{ArgumentResult, ArgumentType},
+ command::Command,
+ redirect_modifier::RedirectModifier,
tree::command_node::CommandNode,
};
use std::collections::HashMap;
@@ -12,7 +14,7 @@ pub struct CommandContext<S> {
source: S,
input: String,
command: dyn Command<S>,
- arguments: HashMap<String, ParsedArgument<S, dyn ArgumentType>>,
+ arguments: HashMap<String, ParsedArgument<dyn ArgumentType<dyn ArgumentResult>>>,
root_node: dyn CommandNode<S>,
nodes: Vec<ParsedCommandNode<S>>,
range: StringRange,
diff --git a/azalea-brigadier/src/context/command_context_builder.rs b/azalea-brigadier/src/context/command_context_builder.rs
index e74b5b1c..ac4a36bb 100644
--- a/azalea-brigadier/src/context/command_context_builder.rs
+++ b/azalea-brigadier/src/context/command_context_builder.rs
@@ -1,8 +1,10 @@
use std::collections::HashMap;
use crate::{
- arguments::argument_type::ArgumentType, command::Command,
- command_dispatcher::CommandDispatcher, redirect_modifier::RedirectModifier,
+ arguments::argument_type::{ArgumentResult, ArgumentType},
+ command::Command,
+ command_dispatcher::CommandDispatcher,
+ redirect_modifier::RedirectModifier,
tree::command_node::CommandNode,
};
@@ -26,7 +28,7 @@ use super::{
#[derive(Clone)]
pub struct CommandContextBuilder<S> {
- arguments: HashMap<String, ParsedArgument<S, dyn ArgumentType>>,
+ arguments: HashMap<String, ParsedArgument<dyn ArgumentType<dyn ArgumentResult>>>,
root_node: dyn CommandNode<S>,
nodes: Vec<ParsedCommandNode<S>>,
dispatcher: CommandDispatcher<S>,
@@ -77,13 +79,15 @@ impl<S> CommandContextBuilder<S> {
pub fn with_argument(
mut self,
name: String,
- argument: ParsedArgument<S, dyn ArgumentType>,
+ argument: ParsedArgument<dyn ArgumentType<dyn ArgumentResult>>,
) -> Self {
self.arguments.insert(name, argument);
self
}
- pub fn arguments(&self) -> &HashMap<String, ParsedArgument<S, dyn ArgumentType>> {
+ pub fn arguments(
+ &self,
+ ) -> &HashMap<String, ParsedArgument<dyn ArgumentType<dyn ArgumentResult>>> {
&self.arguments
}
diff --git a/azalea-brigadier/src/context/parsed_argument.rs b/azalea-brigadier/src/context/parsed_argument.rs
index 5f9c2cdb..77a47078 100644
--- a/azalea-brigadier/src/context/parsed_argument.rs
+++ b/azalea-brigadier/src/context/parsed_argument.rs
@@ -1,12 +1,14 @@
+use std::marker::PhantomData;
+
use super::string_range::StringRange;
#[derive(PartialEq, Eq, Hash)]
-pub struct ParsedArgument<S, T> {
+pub struct ParsedArgument<T> {
range: StringRange,
result: T,
}
-impl<S, T> ParsedArgument<S, T> {
+impl<T> ParsedArgument<T> {
fn new(start: usize, end: usize, result: T) -> Self {
Self {
range: StringRange::between(start, end),
diff --git a/azalea-brigadier/src/tree/argument_command_node.rs b/azalea-brigadier/src/tree/argument_command_node.rs
index df7d3f5c..51add3d5 100644
--- a/azalea-brigadier/src/tree/argument_command_node.rs
+++ b/azalea-brigadier/src/tree/argument_command_node.rs
@@ -1,7 +1,8 @@
use std::fmt::{Display, Formatter};
use crate::{
- arguments::argument_type::ArgumentType,
+ arguments::argument_type::{ArgumentResult, ArgumentType},
+ builder::required_argument_builder::RequiredArgumentBuilder,
context::{
command_context::CommandContext, command_context_builder::CommandContextBuilder,
parsed_argument::ParsedArgument,
@@ -22,14 +23,14 @@ const USAGE_ARGUMENT_CLOSE: &str = ">";
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
pub struct ArgumentCommandNode<S, T> {
name: String,
- type_: dyn ArgumentType,
+ type_: Box<dyn ArgumentType<dyn ArgumentResult>>,
custom_suggestions: dyn SuggestionProvider<S>,
// Since Rust doesn't have extending, we put the struct this is extending as the "base" field
pub base: BaseCommandNode<S>,
}
impl<S, T> ArgumentCommandNode<S, T> {
- fn get_type(&self) -> &dyn ArgumentType {
+ fn get_type(&self) -> &dyn ArgumentType<dyn ArgumentResult> {
&self.type_
}
@@ -45,7 +46,7 @@ impl<S, T> CommandNode<S> for ArgumentCommandNode<S, T> {
fn parse(
&self,
- reader: StringReader,
+ reader: &mut StringReader,
context_builder: CommandContextBuilder<S>,
) -> Result<(), CommandSyntaxException> {
// final int start = reader.getCursor();
@@ -68,7 +69,7 @@ impl<S, T> CommandNode<S> for ArgumentCommandNode<S, T> {
fn list_suggestions(
&self,
context: CommandContext<S>,
- builder: SuggestionsBuilder,
+ builder: &mut SuggestionsBuilder,
) -> Result<Suggestions, CommandSyntaxException> {
if self.custom_suggestions.is_none() {
self.get_type().list_suggestions(context, builder)
diff --git a/azalea-brigadier/src/tree/command_node.rs b/azalea-brigadier/src/tree/command_node.rs
index 286820b9..717ea5f1 100644
--- a/azalea-brigadier/src/tree/command_node.rs
+++ b/azalea-brigadier/src/tree/command_node.rs
@@ -1,6 +1,7 @@
use std::collections::HashMap;
use crate::{
+ arguments::argument_type::{ArgumentResult, ArgumentType},
builder::argument_builder::ArgumentBuilder,
command::Command,
context::{command_context::CommandContext, command_context_builder::CommandContextBuilder},
@@ -13,17 +14,9 @@ use crate::{
use super::{argument_command_node::ArgumentCommandNode, literal_command_node::LiteralCommandNode};
pub struct BaseCommandNode<S> {
- // private final Map<String, CommandNode<S>> children = new LinkedHashMap<>();
- // private final Map<String, LiteralCommandNode<S>> literals = new LinkedHashMap<>();
- // private final Map<String, ArgumentCommandNode<S, ?>> arguments = new LinkedHashMap<>();
- // private final Predicate<S> requirement;
- // private final CommandNode<S> redirect;
- // private final RedirectModifier<S> modifier;
- // private final boolean forks;
- // private Command<S> command;
children: HashMap<String, dyn CommandNode<S>>,
literals: HashMap<String, LiteralCommandNode<S>>,
- arguments: HashMap<String, ArgumentCommandNode<S, _>>,
+ arguments: HashMap<String, ArgumentCommandNode<S, dyn ArgumentType<dyn ArgumentResult>>>,
requirement: Option<dyn Fn(&S) -> bool>,
redirect: Option<dyn CommandNode<S>>,
modifier: Option<dyn RedirectModifier<S>>,