aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-01-10 20:29:46 -0600
committermat <github@matdoes.dev>2022-01-10 20:29:46 -0600
commit60b129b3a62b66dd389d1775892405fe735b9540 (patch)
treeb6d977c8256ffbda97c3822e571ef7c65003750b
parentcb4d871f6f56a484dc87151ea3ad55f7e3bbed97 (diff)
downloadazalea-drasl-60b129b3a62b66dd389d1775892405fe735b9540.tar.xz
progress
-rw-r--r--azalea-brigadier/src/arguments/argument_type.rs28
-rw-r--r--azalea-brigadier/src/arguments/bool_argument_type.rs49
-rw-r--r--azalea-brigadier/src/builder/argument_builder.rs50
-rw-r--r--azalea-brigadier/src/builder/literal_argument_builder.rs32
-rw-r--r--azalea-brigadier/src/builder/required_argument_builder.rs70
-rw-r--r--azalea-brigadier/src/command.rs4
-rw-r--r--azalea-brigadier/src/command_dispatcher.rs26
-rw-r--r--azalea-brigadier/src/context/command_context.rs26
-rw-r--r--azalea-brigadier/src/context/command_context_builder.rs56
-rw-r--r--azalea-brigadier/src/context/parsed_argument.rs3
-rw-r--r--azalea-brigadier/src/context/parsed_command_node.rs10
-rw-r--r--azalea-brigadier/src/context/suggestion_context.rs4
-rw-r--r--azalea-brigadier/src/redirect_modifier.rs4
-rw-r--r--azalea-brigadier/src/single_redirect_modifier.rs4
-rw-r--r--azalea-brigadier/src/suggestion/suggestion_provider.rs4
-rw-r--r--azalea-brigadier/src/tree/argument_command_node.rs24
-rw-r--r--azalea-brigadier/src/tree/command_node.rs28
-rw-r--r--azalea-brigadier/src/tree/literal_command_node.rs26
-rw-r--r--azalea-brigadier/src/tree/root_command_node.rs12
19 files changed, 259 insertions, 201 deletions
diff --git a/azalea-brigadier/src/arguments/argument_type.rs b/azalea-brigadier/src/arguments/argument_type.rs
index f5ca457b..107b1cbf 100644
--- a/azalea-brigadier/src/arguments/argument_type.rs
+++ b/azalea-brigadier/src/arguments/argument_type.rs
@@ -6,27 +6,30 @@ use crate::{
suggestion::{suggestions::Suggestions, suggestions_builder::SuggestionsBuilder},
};
-pub enum DefaultArguments {
- Bool(BoolArgumentType),
+pub trait Types {
+ fn bool(value: bool) -> Self;
}
/*
-define_arguments! {
+#[derive(Types)]
+enum BrigadierTypes {
Entity(EntityArgumentType)
}
===
-enum CustomArguments {
+enum BrigadierTypes {
+ Bool(BoolArgumentType)
+
Entity(EntityArgumentType)
}
-enum BrigadierArguments {
- BuiltIn(DefaultArguments)
- Custom(CustomArguments)
-}
*/
-pub trait ArgumentType<T> {
+pub trait ArgumentType<T>
+where
+ Self: Sized,
+ T: Types,
+{
// T parse(StringReader reader) throws CommandSyntaxException;
// default <S> CompletableFuture<Suggestions> listSuggestions(final CommandContext<S> context, final SuggestionsBuilder builder) {
@@ -41,9 +44,12 @@ pub trait ArgumentType<T> {
fn list_suggestions<S>(
&self,
- context: &CommandContext<S>,
+ context: &CommandContext<S, T>,
builder: &mut SuggestionsBuilder,
- ) -> Result<Suggestions, CommandSyntaxException>;
+ ) -> Result<Suggestions, CommandSyntaxException>
+ where
+ S: Sized,
+ T: Sized;
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 9bdf42e5..dc2c6896 100644
--- a/azalea-brigadier/src/arguments/bool_argument_type.rs
+++ b/azalea-brigadier/src/arguments/bool_argument_type.rs
@@ -1,10 +1,51 @@
-use crate::context::command_context::CommandContext;
+use crate::{
+ context::command_context::CommandContext,
+ exceptions::command_syntax_exception::CommandSyntaxException,
+ string_reader::StringReader,
+ suggestion::{suggestions::Suggestions, suggestions_builder::SuggestionsBuilder},
+};
-use super::argument_type::ArgumentType;
+use super::argument_type::{ArgumentType, Types};
pub struct BoolArgumentType {}
-impl ArgumentType<bool> for BoolArgumentType {}
+impl<T> ArgumentType<T> for BoolArgumentType
+where
+ T: Types,
+{
+ fn parse(&self, reader: &mut StringReader) -> Result<T, CommandSyntaxException> {
+ Ok(T::bool(reader.read_boolean()?))
+ }
+
+ fn list_suggestions<S>(
+ &self,
+ context: &CommandContext<S, T>,
+ builder: &mut SuggestionsBuilder,
+ ) -> Result<Suggestions, CommandSyntaxException>
+ where
+ S: Sized,
+ T: Sized,
+ {
+ // if ("true".startsWith(builder.getRemainingLowerCase())) {
+ // builder.suggest("true");
+ // }
+ // if ("false".startsWith(builder.getRemainingLowerCase())) {
+ // builder.suggest("false");
+ // }
+ // return builder.buildFuture();
+ if "true".starts_with(builder.get_remaining_lower_case()) {
+ builder.suggest("true");
+ }
+ if "false".starts_with(builder.get_remaining_lower_case()) {
+ builder.suggest("false");
+ }
+ Ok(builder.build_future())
+ }
+
+ fn get_examples(&self) -> Vec<String> {
+ vec![]
+ }
+}
impl BoolArgumentType {
const EXAMPLES: &'static [&'static str] = &["true", "false"];
@@ -13,7 +54,7 @@ impl BoolArgumentType {
Self {}
}
- fn get_bool<S>(context: CommandContext<S>, name: String) {
+ fn get_bool<S, T>(context: CommandContext<S, T>, name: String) {
context.get_argument::<bool>(name)
}
}
diff --git a/azalea-brigadier/src/builder/argument_builder.rs b/azalea-brigadier/src/builder/argument_builder.rs
index 19706a22..bd2a2c15 100644
--- a/azalea-brigadier/src/builder/argument_builder.rs
+++ b/azalea-brigadier/src/builder/argument_builder.rs
@@ -5,27 +5,25 @@ use crate::{
tree::{command_node::CommandNode, root_command_node::RootCommandNode},
};
-pub struct BaseArgumentBuilder<S, T>
+pub struct BaseArgumentBuilder<'a, S, T>
where
- T: ArgumentBuilder<S, T>,
+ S: Sized,
+ T: Sized,
{
- arguments: RootCommandNode<S>,
- command: Option<dyn Command<S>>,
- requirement: dyn Fn(&S) -> bool,
- target: Option<dyn CommandNode<S>>,
- modifier: Option<dyn RedirectModifier<S>>,
+ arguments: RootCommandNode<'a, S, T>,
+ command: Option<&'a dyn Command<S, T>>,
+ requirement: &'a dyn Fn(&S) -> bool,
+ target: Option<&'a dyn CommandNode<S, T>>,
+ modifier: Option<&'a dyn RedirectModifier<S, T>>,
forks: bool,
}
pub trait ArgumentBuilder<S, T> {
- fn build(self) -> dyn CommandNode<S>;
+ fn build(self) -> dyn CommandNode<S, T>;
}
-impl<S, T> BaseArgumentBuilder<S, T>
-where
- T: ArgumentBuilder<S, T>,
-{
- pub fn then(&mut self, command: dyn CommandNode<S>) -> Result<&mut T, String> {
+impl<S, T> BaseArgumentBuilder<'_, S, T> {
+ pub fn then(&mut self, command: dyn CommandNode<S, T>) -> Result<&mut T, String> {
if self.target.is_some() {
return Err("Cannot add children to a redirected node".to_string());
}
@@ -33,20 +31,20 @@ where
Ok(self)
}
- pub fn arguments(&self) -> &Vec<dyn CommandNode<S>> {
+ pub fn arguments(&self) -> &Vec<&dyn CommandNode<S, T>> {
&self.arguments.get_children()
}
- pub fn executes(&mut self, command: dyn Command<S>) -> &mut T {
+ pub fn executes(&mut self, command: dyn Command<S, T>) -> &mut T {
self.command = command;
self
}
- pub fn command(&self) -> dyn Command<S> {
+ pub fn command(&self) -> dyn Command<S, T> {
self.command
}
- pub fn requires(&mut self, requirement: dyn Fn(&S) -> bool) -> &mut T {
+ pub fn requires(&mut self, requirement: &dyn Fn(&S) -> bool) -> &mut T {
self.requirement = requirement;
self
}
@@ -55,14 +53,14 @@ where
self.requirement
}
- pub fn redirect(&mut self, target: dyn CommandNode<S>) -> &mut T {
+ pub fn redirect(&mut self, target: &dyn CommandNode<S, T>) -> &mut T {
self.forward(target, None, false)
}
pub fn redirect_modifier(
&mut self,
- target: dyn CommandNode<S>,
- modifier: dyn SingleRedirectModifier<S>,
+ target: &dyn CommandNode<S, T>,
+ modifier: &dyn SingleRedirectModifier<S, T>,
) -> &mut T {
// forward(target, modifier == null ? null : o -> Collections.singleton(modifier.apply(o)), false);
self.forward(target, modifier.map(|m| |o| vec![m.apply(o)]), false)
@@ -70,16 +68,16 @@ where
pub fn fork(
&mut self,
- target: dyn CommandNode<S>,
- modifier: dyn RedirectModifier<S>,
+ target: &dyn CommandNode<S, T>,
+ modifier: &dyn RedirectModifier<S, T>,
) -> &mut T {
self.forward(target, Some(modifier), true)
}
pub fn forward(
&mut self,
- target: dyn CommandNode<S>,
- modifier: Option<dyn RedirectModifier<S>>,
+ target: &dyn CommandNode<S, T>,
+ modifier: Option<&dyn RedirectModifier<S, T>>,
fork: bool,
) -> Result<&mut T, String> {
if !self.arguments.get_children().is_empty() {
@@ -91,11 +89,11 @@ where
Ok(self)
}
- pub fn get_redirect(&self) -> Option<&dyn CommandNode<S>> {
+ pub fn get_redirect(&self) -> Option<&dyn CommandNode<S, T>> {
self.target.as_ref()
}
- pub fn get_redirect_modifier(&self) -> Option<&dyn RedirectModifier<S>> {
+ pub fn get_redirect_modifier(&self) -> Option<&dyn RedirectModifier<S, T>> {
self.modifier.as_ref()
}
diff --git a/azalea-brigadier/src/builder/literal_argument_builder.rs b/azalea-brigadier/src/builder/literal_argument_builder.rs
index e69de29b..cf9f1ee9 100644
--- a/azalea-brigadier/src/builder/literal_argument_builder.rs
+++ b/azalea-brigadier/src/builder/literal_argument_builder.rs
@@ -0,0 +1,32 @@
+use crate::tree::literal_command_node::LiteralCommandNode;
+
+use super::argument_builder::BaseArgumentBuilder;
+
+pub struct LiteralArgumentBuilder<'a, S, T> {
+ literal: String,
+
+ pub base: BaseArgumentBuilder<'a, S, T>,
+}
+
+impl<'a, S, T> LiteralArgumentBuilder<'a, S, T> {
+ pub fn new(literal: String) -> Self {
+ Self {
+ literal,
+ base: BaseArgumentBuilder::default(),
+ }
+ }
+
+ pub fn literal(name: String) -> Self {
+ Self::new(name)
+ }
+
+ pub fn build(self) -> LiteralCommandNode<'a, S, T> {
+ let result = LiteralCommandNode::new(self.literal, self.base);
+
+ for argument in self.base.arguments {
+ result.add_child(argument);
+ }
+
+ result
+ }
+}
diff --git a/azalea-brigadier/src/builder/required_argument_builder.rs b/azalea-brigadier/src/builder/required_argument_builder.rs
index 3ec613c4..6f6fa8eb 100644
--- a/azalea-brigadier/src/builder/required_argument_builder.rs
+++ b/azalea-brigadier/src/builder/required_argument_builder.rs
@@ -1,92 +1,50 @@
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> {
+pub struct RequiredArgumentBuilder<'a, 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>>,
+ type_: &'a T,
+ suggestions_provider: Option<&'a dyn SuggestionProvider<S, T>>,
- pub base: BaseArgumentBuilder<S, T>,
+ pub base: BaseArgumentBuilder<'a, S, T>,
}
-impl<S, T> RequiredArgumentBuilder<S, T> {
- pub fn new(name: String, type_: dyn ArgumentType<T>) -> Self {
+impl<'a, S, T> RequiredArgumentBuilder<'a, S, T> {
+ pub fn new(name: String, type_: T) -> Self {
Self {
name,
- type_,
+ type_: &type_,
suggestions_provider: None,
base: BaseArgumentBuilder::new(name, type_),
}
}
- pub fn argument(name: String, type_: dyn ArgumentType<T>) -> Self {
+ pub fn argument(name: String, type_: T) -> Self {
Self::new(name, type_)
}
- pub fn suggests(mut self, provider: dyn SuggestionProvider<S>) -> Self {
+ pub fn suggests(mut self, provider: &dyn SuggestionProvider<S, T>) -> Self {
self.suggestions_provider = Some(provider);
self
}
- pub fn suggestions_provider(&self) -> Option<&dyn SuggestionProvider<S>> {
+ pub fn suggestions_provider(&self) -> Option<&dyn SuggestionProvider<S, T>> {
self.suggestions_provider.as_ref()
}
- pub fn get_type(&self) -> &dyn ArgumentType<T> {
- &self.type_
+ pub fn get_type(&self) -> &T {
+ self.type_
}
pub fn name(&self) -> &str {
- &self.name
+ self.name
}
// final ArgumentCommandNode<S, T> result = new ArgumentCommandNode<>(getName(), getType(), getCommand(), getRequirement(), getRedirect(), getRedirectModifier(), isFork(), getSuggestionsProvider());
@@ -96,7 +54,7 @@ impl<S, T> RequiredArgumentBuilder<S, T> {
// }
// return result;
- pub fn build(self) -> ArgumentCommandNode<S, T> {
+ pub fn build(self) -> ArgumentCommandNode<'a, S, T> {
let result = ArgumentCommandNode {
name: self.name,
type_: &self.type_,
diff --git a/azalea-brigadier/src/command.rs b/azalea-brigadier/src/command.rs
index a76454b7..520c8a52 100644
--- a/azalea-brigadier/src/command.rs
+++ b/azalea-brigadier/src/command.rs
@@ -5,6 +5,6 @@ use crate::{
pub const SINGLE_SUCCESS: i32 = 1;
-pub trait Command<S> {
- fn run(&self, context: &mut CommandContext<S>) -> Result<i32, CommandSyntaxException>;
+pub trait Command<S, T> {
+ fn run(&self, context: &mut CommandContext<S, T>) -> Result<i32, CommandSyntaxException>;
}
diff --git a/azalea-brigadier/src/command_dispatcher.rs b/azalea-brigadier/src/command_dispatcher.rs
index 0e9b9036..d0351547 100644
--- a/azalea-brigadier/src/command_dispatcher.rs
+++ b/azalea-brigadier/src/command_dispatcher.rs
@@ -2,11 +2,12 @@ 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> {
- root: RootCommandNode<S>,
+#[derive(Default)]
+pub struct CommandDispatcher<'a, S, T> {
+ root: RootCommandNode<'a, S, T>,
}
-impl<S> CommandDispatcher<S> {
+impl<S, T> CommandDispatcher<'_, S, T> {
/// The string required to separate individual arguments in an input string
///
/// See: [`ARGUMENT_SEPARATOR_CHAR`]
@@ -22,4 +23,23 @@ impl<S> CommandDispatcher<S> {
const USAGE_REQUIRED_OPEN: &'static str = "(";
const USAGE_REQUIRED_CLOSE: &'static str = ")";
const USAGE_OR: &'static str = "|";
+
+ /// Create a new [`CommandDispatcher`] with the specified root node.
+ /// This is often useful to copy existing or pre-defined command trees.
+ /// # Example
+ /// ```
+ /// use azalea_brigadier::{
+ /// command_dispatcher::CommandDispatcher,
+ /// tree::root_command_node::RootCommandNode,
+ /// };
+ ///
+ /// let mut dispatcher = CommandDispatcher::new(RootCommandNode::new());
+ /// ```
+ /// # Arguments
+ /// * `root` - the existing [`RootCommandNode`] to use as the basis for this tree
+ /// # Returns
+ /// A new [`CommandDispatcher`] with the specified root node.
+ fn new(root: RootCommandNode<S, T>) -> Self {
+ Self { root }
+ }
}
diff --git a/azalea-brigadier/src/context/command_context.rs b/azalea-brigadier/src/context/command_context.rs
index 7a2189d9..36741906 100644
--- a/azalea-brigadier/src/context/command_context.rs
+++ b/azalea-brigadier/src/context/command_context.rs
@@ -3,27 +3,25 @@ use super::{
string_range::StringRange,
};
use crate::{
- arguments::argument_type::{ArgumentResult, ArgumentType},
- command::Command,
- redirect_modifier::RedirectModifier,
+ arguments::argument_type::ArgumentType, command::Command, redirect_modifier::RedirectModifier,
tree::command_node::CommandNode,
};
use std::collections::HashMap;
-pub struct CommandContext<S> {
+pub struct CommandContext<'a, S, T> {
source: S,
input: String,
- command: dyn Command<S>,
- arguments: HashMap<String, ParsedArgument<dyn ArgumentType<dyn ArgumentResult>>>,
- root_node: dyn CommandNode<S>,
- nodes: Vec<ParsedCommandNode<S>>,
+ command: &'a dyn Command<S, T>,
+ arguments: HashMap<String, ParsedArgument<T>>,
+ root_node: &'a dyn CommandNode<S, T>,
+ nodes: Vec<ParsedCommandNode<'a, S, T>>,
range: StringRange,
- child: Option<CommandContext<S>>,
- modifier: Option<dyn RedirectModifier<S>>,
+ child: Option<CommandContext<'a, S, T>>,
+ modifier: Option<&'a dyn RedirectModifier<S, T>>,
forks: bool,
}
-impl<S> CommandContext<S> {
+impl<S, T> CommandContext<'_, S, T> {
pub fn clone_for(&self, source: S) -> Self {
if self.source == source {
return self.clone();
@@ -42,11 +40,11 @@ impl<S> CommandContext<S> {
}
}
- fn child(&self) -> &Option<CommandContext<S>> {
+ fn child(&self) -> &Option<CommandContext<S, T>> {
&self.child
}
- fn last_child(&self) -> &CommandContext<S> {
+ fn last_child(&self) -> &CommandContext<S, T> {
let mut result = self;
while result.child.is_some() {
result = result.child.as_ref().unwrap();
@@ -54,7 +52,7 @@ impl<S> CommandContext<S> {
result
}
- fn command(&self) -> &dyn Command<S> {
+ fn command(&self) -> &dyn Command<S, T> {
&self.command
}
diff --git a/azalea-brigadier/src/context/command_context_builder.rs b/azalea-brigadier/src/context/command_context_builder.rs
index 5766ea9a..878d7692 100644
--- a/azalea-brigadier/src/context/command_context_builder.rs
+++ b/azalea-brigadier/src/context/command_context_builder.rs
@@ -25,16 +25,16 @@ use super::{
// private boolean forks;
#[derive(Clone)]
-pub struct CommandContextBuilder<S> {
- arguments: HashMap<String, ParsedArgument<dyn ArgumentType<dyn ArgumentResult>>>,
- root_node: dyn CommandNode<S>,
- nodes: Vec<ParsedCommandNode<S>>,
- dispatcher: CommandDispatcher<S>,
+pub struct CommandContextBuilder<'a, S, T> {
+ arguments: HashMap<String, ParsedArgument<T>>,
+ root_node: &'a dyn CommandNode<S, T>,
+ nodes: Vec<ParsedCommandNode<'a, S, T>>,
+ dispatcher: CommandDispatcher<'a, S, T>,
source: S,
- command: Box<dyn Command<S>>,
- child: Option<CommandContextBuilder<S>>,
+ command: Box<dyn Command<S, T>>,
+ child: Option<CommandContextBuilder<'a, S, T>>,
range: StringRange,
- modifier: Option<Box<dyn RedirectModifier<S>>>,
+ modifier: Option<Box<dyn RedirectModifier<S, T>>>,
forks: bool,
}
@@ -45,15 +45,15 @@ pub struct CommandContextBuilder<S> {
// this.range = StringRange.at(start);
// }
-impl<S> CommandContextBuilder<S> {
+impl<S, T> CommandContextBuilder<'_, S, T> {
pub fn new(
- dispatcher: CommandDispatcher<S>,
+ dispatcher: CommandDispatcher<S, T>,
source: S,
- root_node: dyn CommandNode<S>,
+ root_node: dyn CommandNode<S, T>,
start: usize,
) -> Self {
Self {
- root_node,
+ root_node: &root_node,
dispatcher,
source,
range: StringRange::at(start),
@@ -70,31 +70,25 @@ impl<S> CommandContextBuilder<S> {
&self.source
}
- pub fn root_node(&self) -> &dyn CommandNode<S> {
+ pub fn root_node(&self) -> &dyn CommandNode<S, T> {
&self.root_node
}
- pub fn with_argument(
- mut self,
- name: String,
- argument: ParsedArgument<dyn ArgumentType<dyn ArgumentResult>>,
- ) -> Self {
+ pub fn with_argument(mut self, name: String, argument: ParsedArgument<T>) -> Self {
self.arguments.insert(name, argument);
self
}
- pub fn arguments(
- &self,
- ) -> &HashMap<String, ParsedArgument<dyn ArgumentType<dyn ArgumentResult>>> {
+ pub fn arguments(&self) -> &HashMap<String, ParsedArgument<T>> {
&self.arguments
}
- pub fn with_command(mut self, command: Box<dyn Command<S>>) -> Self {
+ pub fn with_command(mut self, command: &dyn Command<S, T>) -> Self {
self.command = command;
self
}
- pub fn with_node(mut self, node: dyn CommandNode<S>, range: StringRange) -> Self {
+ pub fn with_node(mut self, node: dyn CommandNode<S, T>, range: StringRange) -> Self {
self.nodes.push(ParsedCommandNode::new(node, range));
self.range = StringRange::encompassing(&self.range, &range);
self.modifier = node.redirect_modifier();
@@ -102,16 +96,16 @@ impl<S> CommandContextBuilder<S> {
self
}
- pub fn with_child(mut self, child: CommandContextBuilder<S>) -> Self {
+ pub fn with_child(mut self, child: CommandContextBuilder<S, T>) -> Self {
self.child = Some(child);
self
}
- pub fn child(&self) -> Option<&CommandContextBuilder<S>> {
+ pub fn child(&self) -> Option<&CommandContextBuilder<S, T>> {
self.child.as_ref()
}
- pub fn last_child(&self) -> Option<&CommandContextBuilder<S>> {
+ pub fn last_child(&self) -> Option<&CommandContextBuilder<S, T>> {
let mut result = self;
while let Some(child) = result.child() {
result = child;
@@ -119,15 +113,15 @@ impl<S> CommandContextBuilder<S> {
Some(result)
}
- pub fn command(&self) -> &dyn Command<S> {
+ pub fn command(&self) -> &dyn Command<S, T> {
&*self.command
}
- pub fn nodes(&self) -> &Vec<ParsedCommandNode<S>> {
+ pub fn nodes(&self) -> &Vec<ParsedCommandNode<S, T>> {
&self.nodes
}
- pub fn build(self, input: &str) -> CommandContext<S> {
+ pub fn build(self, input: &str) -> CommandContext<S, T> {
CommandContext {
source: self.source,
input,
@@ -142,7 +136,7 @@ impl<S> CommandContextBuilder<S> {
}
}
- pub fn dispatcher(&self) -> &CommandDispatcher<S> {
+ pub fn dispatcher(&self) -> &CommandDispatcher<S, T> {
&self.dispatcher
}
@@ -150,7 +144,7 @@ impl<S> CommandContextBuilder<S> {
&self.range
}
- pub fn find_suggestion_context(&self, cursor: i32) -> Result<SuggestionContext<S>, String> {
+ pub fn find_suggestion_context(&self, cursor: i32) -> Result<SuggestionContext<S, T>, String> {
if self.range.start() <= cursor {
if self.range.end() < cursor {
if let Some(child) = self.child() {
diff --git a/azalea-brigadier/src/context/parsed_argument.rs b/azalea-brigadier/src/context/parsed_argument.rs
index 77a47078..75c07784 100644
--- a/azalea-brigadier/src/context/parsed_argument.rs
+++ b/azalea-brigadier/src/context/parsed_argument.rs
@@ -1,10 +1,9 @@
-use std::marker::PhantomData;
-
use super::string_range::StringRange;
#[derive(PartialEq, Eq, Hash)]
pub struct ParsedArgument<T> {
range: StringRange,
+ // T is an item in an enum
result: T,
}
diff --git a/azalea-brigadier/src/context/parsed_command_node.rs b/azalea-brigadier/src/context/parsed_command_node.rs
index 98e99959..a006aa4b 100644
--- a/azalea-brigadier/src/context/parsed_command_node.rs
+++ b/azalea-brigadier/src/context/parsed_command_node.rs
@@ -2,17 +2,17 @@ use super::string_range::StringRange;
use crate::tree::command_node::CommandNode;
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
-pub struct ParsedCommandNode<S> {
- node: dyn CommandNode<S>,
+pub struct ParsedCommandNode<'a, S, T> {
+ node: &'a dyn CommandNode<S, T>,
range: StringRange,
}
-impl<S> ParsedCommandNode<S> {
- fn new(node: dyn CommandNode<S>, range: StringRange) -> Self {
+impl<S, T> ParsedCommandNode<'_, S, T> {
+ fn new(node: &dyn CommandNode<S, T>, range: StringRange) -> Self {
Self { node, range }
}
- fn node(&self) -> &dyn CommandNode<S> {
+ fn node(&self) -> &dyn CommandNode<S, T> {
&self.node
}
diff --git a/azalea-brigadier/src/context/suggestion_context.rs b/azalea-brigadier/src/context/suggestion_context.rs
index 540a5f23..42bc550e 100644
--- a/azalea-brigadier/src/context/suggestion_context.rs
+++ b/azalea-brigadier/src/context/suggestion_context.rs
@@ -1,6 +1,6 @@
use crate::tree::command_node::CommandNode;
-pub struct SuggestionContext<S> {
- parent: dyn CommandNode<S>,
+pub struct SuggestionContext<'a, S, T> {
+ parent: &'a dyn CommandNode<S, T>,
start_pos: usize,
}
diff --git a/azalea-brigadier/src/redirect_modifier.rs b/azalea-brigadier/src/redirect_modifier.rs
index cfefd120..fd2e1bf7 100644
--- a/azalea-brigadier/src/redirect_modifier.rs
+++ b/azalea-brigadier/src/redirect_modifier.rs
@@ -3,6 +3,6 @@ use crate::{
exceptions::command_syntax_exception::CommandSyntaxException,
};
-pub trait RedirectModifier<S> {
- fn apply(&self, context: CommandContext<S>) -> Result<Vec<S>, CommandSyntaxException>;
+pub trait RedirectModifier<S, T> {
+ fn apply(&self, context: CommandContext<S, T>) -> Result<Vec<S>, CommandSyntaxException>;
}
diff --git a/azalea-brigadier/src/single_redirect_modifier.rs b/azalea-brigadier/src/single_redirect_modifier.rs
index dd63244d..95055fd8 100644
--- a/azalea-brigadier/src/single_redirect_modifier.rs
+++ b/azalea-brigadier/src/single_redirect_modifier.rs
@@ -3,6 +3,6 @@ use crate::{
exceptions::command_syntax_exception::CommandSyntaxException,
};
-pub trait SingleRedirectModifier<S> {
- fn apply(&self, context: CommandContext<S>) -> Result<S, CommandSyntaxException>;
+pub trait SingleRedirectModifier<S, T> {
+ fn apply(&self, context: CommandContext<S, T>) -> Result<S, CommandSyntaxException>;
}
diff --git a/azalea-brigadier/src/suggestion/suggestion_provider.rs b/azalea-brigadier/src/suggestion/suggestion_provider.rs
index 3027d460..9720d3b9 100644
--- a/azalea-brigadier/src/suggestion/suggestion_provider.rs
+++ b/azalea-brigadier/src/suggestion/suggestion_provider.rs
@@ -5,10 +5,10 @@ use crate::{
use super::{suggestions::Suggestions, suggestions_builder::SuggestionsBuilder};
-pub trait SuggestionProvider<S> {
+pub trait SuggestionProvider<S, T> {
fn suggestions(
&self,
- context: &CommandContext<S>,
+ context: &CommandContext<S, T>,
builder: &SuggestionsBuilder,
) -> Result<Suggestions, CommandSyntaxException>;
}
diff --git a/azalea-brigadier/src/tree/argument_command_node.rs b/azalea-brigadier/src/tree/argument_command_node.rs
index 51add3d5..4d38b41f 100644
--- a/azalea-brigadier/src/tree/argument_command_node.rs
+++ b/azalea-brigadier/src/tree/argument_command_node.rs
@@ -1,7 +1,7 @@
use std::fmt::{Display, Formatter};
use crate::{
- arguments::argument_type::{ArgumentResult, ArgumentType},
+ arguments::argument_type::ArgumentType,
builder::required_argument_builder::RequiredArgumentBuilder,
context::{
command_context::CommandContext, command_context_builder::CommandContextBuilder,
@@ -21,25 +21,25 @@ const USAGE_ARGUMENT_OPEN: &str = "<";
const USAGE_ARGUMENT_CLOSE: &str = ">";
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
-pub struct ArgumentCommandNode<S, T> {
+pub struct ArgumentCommandNode<'a, S, T> {
name: String,
- type_: Box<dyn ArgumentType<dyn ArgumentResult>>,
- custom_suggestions: dyn SuggestionProvider<S>,
+ type_: &'a T,
+ custom_suggestions: &'a dyn SuggestionProvider<S, T>,
// Since Rust doesn't have extending, we put the struct this is extending as the "base" field
- pub base: BaseCommandNode<S>,
+ pub base: BaseCommandNode<'a, S, T>,
}
-impl<S, T> ArgumentCommandNode<S, T> {
- fn get_type(&self) -> &dyn ArgumentType<dyn ArgumentResult> {
+impl<S, T> ArgumentCommandNode<'_, S, T> {
+ fn get_type(&self) -> &T {
&self.type_
}
- fn custom_suggestions(&self) -> &dyn SuggestionProvider<S> {
+ fn custom_suggestions(&self) -> &dyn SuggestionProvider<S, T> {
&self.custom_suggestions
}
}
-impl<S, T> CommandNode<S> for ArgumentCommandNode<S, T> {
+impl<S, T> CommandNode<S, T> for ArgumentCommandNode<'_, S, T> {
fn name(&self) -> &str {
&self.name
}
@@ -47,7 +47,7 @@ impl<S, T> CommandNode<S> for ArgumentCommandNode<S, T> {
fn parse(
&self,
reader: &mut StringReader,
- context_builder: CommandContextBuilder<S>,
+ context_builder: CommandContextBuilder<S, T>,
) -> Result<(), CommandSyntaxException> {
// final int start = reader.getCursor();
// final T result = type.parse(reader);
@@ -68,7 +68,7 @@ impl<S, T> CommandNode<S> for ArgumentCommandNode<S, T> {
fn list_suggestions(
&self,
- context: CommandContext<S>,
+ context: CommandContext<S, T>,
builder: &mut SuggestionsBuilder,
) -> Result<Suggestions, CommandSyntaxException> {
if self.custom_suggestions.is_none() {
@@ -112,7 +112,7 @@ impl<S, T> CommandNode<S> for ArgumentCommandNode<S, T> {
}
}
-impl Display for ArgumentCommandNode<String, String> {
+impl Display for ArgumentCommandNode<'_, String, String> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "<argument {}: {}>", self.name, self.type_)
}
diff --git a/azalea-brigadier/src/tree/command_node.rs b/azalea-brigadier/src/tree/command_node.rs
index 0d9212aa..bcba9c03 100644
--- a/azalea-brigadier/src/tree/command_node.rs
+++ b/azalea-brigadier/src/tree/command_node.rs
@@ -1,7 +1,7 @@
use std::collections::HashMap;
use crate::{
- arguments::argument_type::{ArgumentResult, ArgumentType},
+ arguments::argument_type::ArgumentType,
builder::argument_builder::ArgumentBuilder,
command::Command,
context::{command_context::CommandContext, command_context_builder::CommandContextBuilder},
@@ -13,33 +13,33 @@ use crate::{
use super::{argument_command_node::ArgumentCommandNode, literal_command_node::LiteralCommandNode};
-pub struct BaseCommandNode<S> {
- children: HashMap<String, dyn CommandNode<S>>,
- literals: HashMap<String, LiteralCommandNode<S>>,
- arguments: HashMap<String, ArgumentCommandNode<S, dyn ArgumentType<ArgumentResult>>>,
- requirement: Option<dyn Fn(&S) -> bool>,
- redirect: Option<dyn CommandNode<S>>,
- modifier: Option<dyn RedirectModifier<S>>,
+pub struct BaseCommandNode<'a, S, T> {
+ children: HashMap<String, &'a dyn CommandNode<S, T>>,
+ literals: HashMap<String, LiteralCommandNode<'a, S, T>>,
+ arguments: HashMap<String, ArgumentCommandNode<'a, S, T>>,
+ requirement: Option<&'a dyn Fn(&S) -> bool>,
+ redirect: Option<&'a dyn CommandNode<S, T>>,
+ modifier: Option<&'a dyn RedirectModifier<S, T>>,
forks: bool,
- command: Option<dyn Command<S>>,
+ command: Option<&'a dyn Command<S, T>>,
}
-impl<S> BaseCommandNode<S> {}
+impl<S, T> BaseCommandNode<'_, S, T> {}
-pub trait CommandNode<S> {
+pub trait CommandNode<S, T> {
fn name(&self) -> &str;
fn usage_text(&self) -> &str;
fn parse(
&self,
reader: StringReader,
- context_builder: CommandContextBuilder<S>,
+ context_builder: CommandContextBuilder<S, T>,
) -> Result<(), CommandSyntaxException>;
fn list_suggestions(
&self,
- context: CommandContext<S>,
+ context: CommandContext<S, T>,
builder: SuggestionsBuilder,
) -> Result<Suggestions, CommandSyntaxException>;
fn is_valid_input(&self, input: &str) -> bool;
- fn create_builder<T>(&self) -> dyn ArgumentBuilder<S, T>;
+ fn create_builder(&self) -> dyn ArgumentBuilder<S, T>;
fn get_examples(&self) -> Vec<String>;
}
diff --git a/azalea-brigadier/src/tree/literal_command_node.rs b/azalea-brigadier/src/tree/literal_command_node.rs
index bb0e613c..fe933669 100644
--- a/azalea-brigadier/src/tree/literal_command_node.rs
+++ b/azalea-brigadier/src/tree/literal_command_node.rs
@@ -1,8 +1,11 @@
use crate::{
+ builder::literal_argument_builder::LiteralArgumentBuilder,
+ command::Command,
context::{command_context::CommandContext, command_context_builder::CommandContextBuilder},
exceptions::{
builtin_exceptions::BuiltInExceptions, command_syntax_exception::CommandSyntaxException,
},
+ redirect_modifier::RedirectModifier,
string_reader::StringReader,
suggestion::{suggestions::Suggestions, suggestions_builder::SuggestionsBuilder},
};
@@ -10,14 +13,23 @@ use crate::{
use super::command_node::{BaseCommandNode, CommandNode};
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
-pub struct LiteralCommandNode<S> {
+pub struct LiteralCommandNode<'a, S, T> {
literal: String,
literal_lowercase: String,
// Since Rust doesn't have extending, we put the struct this is extending as the "base" field
- pub base: BaseCommandNode<S>,
+ pub base: BaseCommandNode<'a, S, T>,
}
-impl<S> LiteralCommandNode<S> {
+impl<'a, S, T> LiteralCommandNode<'a, S, T> {
+ pub fn new(literal: String, base: BaseCommandNode<S, T>) -> Self {
+ let literal_lowercase = literal.to_lowercase();
+ Self {
+ literal,
+ literal_lowercase,
+ base,
+ }
+ }
+
pub fn literal(&self) -> &String {
&self.literal
}
@@ -39,7 +51,7 @@ impl<S> LiteralCommandNode<S> {
}
}
-impl<S> CommandNode<S> for LiteralCommandNode<S> {
+impl<S, T> CommandNode<S, T> for LiteralCommandNode<'_, S, T> {
fn name(&self) -> &str {
&self.literal
}
@@ -47,7 +59,7 @@ impl<S> CommandNode<S> for LiteralCommandNode<S> {
fn parse(
&self,
reader: StringReader,
- context_builder: CommandContextBuilder<S>,
+ context_builder: CommandContextBuilder<S, T>,
) -> Result<(), CommandSyntaxException> {
let start = reader.get_cursor();
let end = self.parse(reader);
@@ -63,7 +75,7 @@ impl<S> CommandNode<S> for LiteralCommandNode<S> {
fn list_suggestions(
&self,
- context: CommandContext<S>,
+ context: CommandContext<S, T>,
builder: SuggestionsBuilder,
) -> Result<Suggestions, CommandSyntaxException> {
if self
@@ -84,7 +96,7 @@ impl<S> CommandNode<S> for LiteralCommandNode<S> {
self.literal
}
- fn create_builder(&self) -> LiteralArgumentBuilder<S> {
+ fn create_builder(&self) -> LiteralArgumentBuilder<S, T> {
let builder = LiteralArgumentBuilder::literal(self.literal());
builder.requires(self.requirement());
builder.forward(self.redirect(), self.redirect_modifier(), self.is_fork());
diff --git a/azalea-brigadier/src/tree/root_command_node.rs b/azalea-brigadier/src/tree/root_command_node.rs
index 004ab6a8..25a5a4b2 100644
--- a/azalea-brigadier/src/tree/root_command_node.rs
+++ b/azalea-brigadier/src/tree/root_command_node.rs
@@ -12,12 +12,12 @@ use crate::{
use super::command_node::{BaseCommandNode, CommandNode};
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
-pub struct RootCommandNode<S> {
+pub struct RootCommandNode<'a, S, T> {
// Since Rust doesn't have extending, we put the struct this is extending as the "base" field
- pub base: BaseCommandNode<S>,
+ pub base: BaseCommandNode<'a, S, T>,
}
-impl<S> CommandNode<S> for RootCommandNode<S> {
+impl<S, T> CommandNode<S, T> for RootCommandNode<'_, S, T> {
fn name(&self) -> &str {
""
}
@@ -25,13 +25,13 @@ impl<S> CommandNode<S> for RootCommandNode<S> {
fn parse(
&self,
reader: StringReader,
- context_builder: CommandContextBuilder<S>,
+ context_builder: CommandContextBuilder<S, T>,
) -> Result<(), CommandSyntaxException> {
}
fn list_suggestions(
&self,
- context: CommandContext<S>,
+ context: CommandContext<S, T>,
builder: SuggestionsBuilder,
) -> Result<Suggestions, CommandSyntaxException> {
Suggestions::empty()
@@ -54,7 +54,7 @@ impl<S> CommandNode<S> for RootCommandNode<S> {
}
}
-impl Display for RootCommandNode<()> {
+impl<S, T> Display for RootCommandNode<'_, S, T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "<root>")
}