aboutsummaryrefslogtreecommitdiff
path: root/azalea-brigadier/src
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-02-03 02:16:24 +0000
committermat <github@matdoes.dev>2022-02-03 02:16:24 +0000
commit4ff67d4917ce333232189e86aee09f2d82451fc6 (patch)
tree07c8688f54084d8ebbade9b13ac22e7d50a91e64 /azalea-brigadier/src
parent1b888881516c7553126e0c7fc2539d14b129e29e (diff)
downloadazalea-drasl-4ff67d4917ce333232189e86aee09f2d82451fc6.tar.xz
a
Diffstat (limited to 'azalea-brigadier/src')
-rw-r--r--azalea-brigadier/src/builder/literal_argument_builder.rs17
-rw-r--r--azalea-brigadier/src/command_dispatcher.rs6
-rw-r--r--azalea-brigadier/src/lib.rs3
-rw-r--r--azalea-brigadier/src/tree/argument_command_node.rs24
-rw-r--r--azalea-brigadier/src/tree/command_node.rs56
-rw-r--r--azalea-brigadier/src/tree/literal_command_node.rs30
-rw-r--r--azalea-brigadier/src/tree/root_command_node.rs19
7 files changed, 71 insertions, 84 deletions
diff --git a/azalea-brigadier/src/builder/literal_argument_builder.rs b/azalea-brigadier/src/builder/literal_argument_builder.rs
index 8250d45d..4a95755c 100644
--- a/azalea-brigadier/src/builder/literal_argument_builder.rs
+++ b/azalea-brigadier/src/builder/literal_argument_builder.rs
@@ -10,11 +10,8 @@ use crate::{
};
use std::fmt::Debug;
-pub struct LiteralArgumentBuilder<'a, S>
-where
- ,
-{
- arguments: RootCommandNode<'a, S>,
+pub struct LiteralArgumentBuilder<S> {
+ arguments: RootCommandNode<S>,
command: Option<Box<dyn Command<S>>>,
requirement: Box<dyn Fn(&S) -> bool>,
target: Option<Box<dyn CommandNodeTrait<S>>>,
@@ -23,10 +20,7 @@ where
literal: String,
}
-impl<'a, S> LiteralArgumentBuilder<'a, S>
-where
- ,
-{
+impl<S> LiteralArgumentBuilder<S> {
pub fn new(literal: String) -> Self {
Self {
literal,
@@ -44,10 +38,7 @@ where
}
}
-impl<'a, S> ArgumentBuilder<S> for LiteralArgumentBuilder<'a, S>
-where
- ,
-{
+impl<S> ArgumentBuilder<S> for LiteralArgumentBuilder<S> {
fn build(self) -> Box<dyn CommandNodeTrait<S>> {
let result = LiteralCommandNode::new(self.literal, self.base.build());
diff --git a/azalea-brigadier/src/command_dispatcher.rs b/azalea-brigadier/src/command_dispatcher.rs
index 98288a48..f8ffddff 100644
--- a/azalea-brigadier/src/command_dispatcher.rs
+++ b/azalea-brigadier/src/command_dispatcher.rs
@@ -4,11 +4,11 @@ use std::fmt::Debug;
/// 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
#[derive(Default, Clone)]
-pub struct CommandDispatcher<'a, S> {
- root: RootCommandNode<'a, S>,
+pub struct CommandDispatcher<S> {
+ root: RootCommandNode<S>,
}
-impl<S> CommandDispatcher<'_, S> {
+impl<S> CommandDispatcher<S> {
/// The string required to separate individual arguments in an input string
///
/// See: [`ARGUMENT_SEPARATOR_CHAR`]
diff --git a/azalea-brigadier/src/lib.rs b/azalea-brigadier/src/lib.rs
index b2345abb..a1ac267c 100644
--- a/azalea-brigadier/src/lib.rs
+++ b/azalea-brigadier/src/lib.rs
@@ -1,6 +1,9 @@
#[macro_use]
extern crate lazy_static;
+#[macro_use]
+extern crate enum_dispatch;
+
mod ambiguity_consumer;
mod arguments;
mod builder;
diff --git a/azalea-brigadier/src/tree/argument_command_node.rs b/azalea-brigadier/src/tree/argument_command_node.rs
index 0997ec17..9d2af14e 100644
--- a/azalea-brigadier/src/tree/argument_command_node.rs
+++ b/azalea-brigadier/src/tree/argument_command_node.rs
@@ -31,18 +31,14 @@ use super::{
const USAGE_ARGUMENT_OPEN: &str = "<";
const USAGE_ARGUMENT_CLOSE: &str = ">";
-#[derive(Clone, Debug)]
-pub struct ArgumentCommandNode<'a, S> {
+pub struct ArgumentCommandNode<S> {
name: String,
type_: Box<dyn ArgumentType<Into = dyn Any>>,
- custom_suggestions: Option<&'a dyn SuggestionProvider<S>>,
- // custom_suggestions: &'a dyn SuggestionProvider<S>,
- // Since Rust doesn't have extending, we put the struct this is extending as the "base" field
- pub base: BaseCommandNode<'a, S>,
+ custom_suggestions: Option<Box<dyn SuggestionProvider<S>>>,
children: HashMap<String, Box<dyn CommandNodeTrait<S>>>,
- literals: HashMap<String, LiteralCommandNode<'a, S>>,
- arguments: HashMap<String, ArgumentCommandNode<'a, S>>,
+ literals: HashMap<String, LiteralCommandNode<S>>,
+ arguments: HashMap<String, ArgumentCommandNode<S>>,
pub requirement: Box<dyn Fn(&S) -> bool>,
redirect: Option<Box<dyn CommandNodeTrait<S>>>,
modifier: Option<Box<dyn RedirectModifier<S>>>,
@@ -50,17 +46,17 @@ pub struct ArgumentCommandNode<'a, S> {
pub command: Option<Box<dyn Command<S>>>,
}
-impl<S> ArgumentCommandNode<'_, S> {
+impl<S> ArgumentCommandNode<S> {
fn get_type(&self) -> &dyn ArgumentType<Into = dyn Any> {
- self.type_
+ &*self.type_
}
- fn custom_suggestions(&self) -> Option<&dyn SuggestionProvider<S>> {
- self.custom_suggestions
+ fn custom_suggestions(&self) -> &Option<Box<dyn SuggestionProvider<S>>> {
+ &self.custom_suggestions
}
}
-impl<'a, S> CommandNodeTrait<S> for ArgumentCommandNode<'a, S> {
+impl<S> CommandNodeTrait<S> for ArgumentCommandNode<S> {
fn name(&self) -> &str {
&self.name
}
@@ -173,7 +169,7 @@ impl<'a, S> CommandNodeTrait<S> for ArgumentCommandNode<'a, S> {
}
}
-impl<S> Display for ArgumentCommandNode<'_, S> {
+impl<S> Display for ArgumentCommandNode<S> {
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 30907163..207e114e 100644
--- a/azalea-brigadier/src/tree/command_node.rs
+++ b/azalea-brigadier/src/tree/command_node.rs
@@ -15,43 +15,14 @@ use crate::{
use std::ops::Deref;
use std::{any::Any, collections::HashMap, fmt::Debug};
-enum CommandNodeEnum<'a, S> {
- Literal(LiteralCommandNode<'a, S>),
- Argument(ArgumentCommandNode<'a, S>),
- Root(RootCommandNode<'a, S>),
+#[enum_dispatch(CommandNodeTrait)]
+enum CommandNodeEnum<S> {
+ Literal(LiteralCommandNode<S>),
+ Argument(ArgumentCommandNode<S>),
+ Root(RootCommandNode<S>),
}
-impl<'a, S> Deref for CommandNodeEnum<'a, S> {
- type Target = dyn CommandNodeTrait<S>;
-
- fn deref(&self) -> &Self::Target {
- match self {
- CommandNodeEnum::Literal(node) => *node as &Self::Target,
- CommandNodeEnum::Argument(node) => *node as &Self::Target,
- CommandNodeEnum::Root(node) => *node as &Self::Target,
- }
- }
-}
-
-impl<S> From<LiteralCommandNode<'_, S>> for CommandNodeEnum<'_, S> {
- fn from(node: LiteralCommandNode<'_, S>) -> Self {
- CommandNodeEnum::Literal(node)
- }
-}
-
-impl<S> From<ArgumentCommandNode<'_, S>> for CommandNodeEnum<'_, S> {
- fn from(node: ArgumentCommandNode<'_, S>) -> Self {
- CommandNodeEnum::Argument(node)
- }
-}
-
-impl<S> From<RootCommandNode<'_, S>> for CommandNodeEnum<'_, S> {
- fn from(node: RootCommandNode<'_, S>) -> Self {
- CommandNodeEnum::Root(node)
- }
-}
-
-impl<S> CommandNodeEnum<'_, S> {
+impl<S> CommandNodeEnum<S> {
fn redirect_modifier(&self) -> Option<&dyn RedirectModifier<S>> {
(*self).modifier.as_ref().map(|modifier| modifier.as_ref())
}
@@ -92,10 +63,10 @@ impl<S> CommandNodeEnum<'_, S> {
}
}
}
-pub struct BaseCommandNode<'a, S> {
+pub struct BaseCommandNode<S> {
children: HashMap<String, Box<dyn CommandNodeTrait<S>>>,
- literals: HashMap<String, LiteralCommandNode<'a, S>>,
- arguments: HashMap<String, ArgumentCommandNode<'a, S>>,
+ literals: HashMap<String, LiteralCommandNode<S>>,
+ arguments: HashMap<String, ArgumentCommandNode<S>>,
pub requirement: Box<dyn Fn(&S) -> bool>,
redirect: Option<Box<dyn CommandNodeTrait<S>>>,
modifier: Option<Box<dyn RedirectModifier<S>>>,
@@ -118,7 +89,7 @@ pub struct BaseCommandNode<'a, S> {
// }
// }
-impl<S> Debug for BaseCommandNode<'_, S> {
+impl<S> Debug for BaseCommandNode<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BaseCommandNode")
.field("children", &self.children)
@@ -133,7 +104,7 @@ impl<S> Debug for BaseCommandNode<'_, S> {
}
}
-impl<S> Default for BaseCommandNode<'_, S> {
+impl<S> Default for BaseCommandNode<S> {
fn default() -> Self {
Self {
children: HashMap::new(),
@@ -148,6 +119,7 @@ impl<S> Default for BaseCommandNode<'_, S> {
}
}
+#[enum_dispatch]
pub trait CommandNodeTrait<S> {
fn name(&self) -> &str;
fn usage_text(&self) -> &str;
@@ -164,4 +136,8 @@ pub trait CommandNodeTrait<S> {
fn is_valid_input(&self, input: &str) -> bool;
fn create_builder(&self) -> Box<dyn ArgumentBuilder<S>>;
fn get_examples(&self) -> Vec<String>;
+
+ fn redirect_modifier(&self) -> Option<&dyn RedirectModifier<S>>;
+ fn can_use(&self, source: S) -> bool;
+ fn add_child(&self, node: &Box<dyn CommandNodeTrait<S>>) -> Result<(), String>;
}
diff --git a/azalea-brigadier/src/tree/literal_command_node.rs b/azalea-brigadier/src/tree/literal_command_node.rs
index 253b6dc5..2db31d97 100644
--- a/azalea-brigadier/src/tree/literal_command_node.rs
+++ b/azalea-brigadier/src/tree/literal_command_node.rs
@@ -3,33 +3,45 @@ use crate::{
builder::{
argument_builder::ArgumentBuilder, literal_argument_builder::LiteralArgumentBuilder,
},
+ command::Command,
context::{command_context::CommandContext, command_context_builder::CommandContextBuilder},
exceptions::{
builtin_exceptions::BuiltInExceptions, command_syntax_exception::CommandSyntaxException,
},
immutable_string_reader::ImmutableStringReader,
+ redirect_modifier::RedirectModifier,
string_reader::StringReader,
suggestion::{suggestions::Suggestions, suggestions_builder::SuggestionsBuilder},
};
-use std::fmt::Debug;
+use std::{collections::HashMap, fmt::Debug};
-use super::command_node::{BaseCommandNode, CommandNodeTrait};
+use super::{
+ argument_command_node::ArgumentCommandNode,
+ command_node::{BaseCommandNode, CommandNodeTrait},
+};
#[derive(Debug, Clone)]
-pub struct LiteralCommandNode<'a, S> {
+pub struct LiteralCommandNode<S> {
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<'a, S>,
+
+ children: HashMap<String, Box<dyn CommandNodeTrait<S>>>,
+ literals: HashMap<String, LiteralCommandNode<S>>,
+ arguments: HashMap<String, ArgumentCommandNode<S>>,
+ pub requirement: Box<dyn Fn(&S) -> bool>,
+ redirect: Option<Box<dyn CommandNodeTrait<S>>>,
+ modifier: Option<Box<dyn RedirectModifier<S>>>,
+ forks: bool,
+ pub command: Option<Box<dyn Command<S>>>,
}
-impl<'a, S> LiteralCommandNode<'a, S> {
- pub fn new(literal: String, base: BaseCommandNode<'a, S>) -> Self {
+impl<S> LiteralCommandNode<S> {
+ pub fn new(literal: String) -> Self {
let literal_lowercase = literal.to_lowercase();
Self {
literal,
literal_lowercase,
- base,
+ ..Default::default()
}
}
@@ -54,7 +66,7 @@ impl<'a, S> LiteralCommandNode<'a, S> {
}
}
-impl<S> CommandNodeTrait<S> for LiteralCommandNode<'_, S> {
+impl<S> CommandNodeTrait<S> for LiteralCommandNode<S> {
fn name(&self) -> &str {
&self.literal
}
diff --git a/azalea-brigadier/src/tree/root_command_node.rs b/azalea-brigadier/src/tree/root_command_node.rs
index 0fcb8d97..6b8bc157 100644
--- a/azalea-brigadier/src/tree/root_command_node.rs
+++ b/azalea-brigadier/src/tree/root_command_node.rs
@@ -6,6 +6,7 @@ use super::{
use crate::{
arguments::argument_type::ArgumentType,
builder::argument_builder::ArgumentBuilder,
+ command::Command,
context::{command_context::CommandContext, command_context_builder::CommandContextBuilder},
exceptions::{
builtin_exceptions::BuiltInExceptions, command_syntax_exception::CommandSyntaxException,
@@ -16,16 +17,24 @@ use crate::{
};
use std::{
any::Any,
+ collections::HashMap,
fmt::{Debug, Display, Formatter},
};
-#[derive(Clone, Default, Debug)]
-pub struct RootCommandNode<'a, S> {
+#[derive(Default)]
+pub struct RootCommandNode<S> {
// Since Rust doesn't have extending, we put the struct this is extending as the "base" field
- pub base: BaseCommandNode<'a, S>,
+ children: HashMap<String, Box<dyn CommandNodeTrait<S>>>,
+ literals: HashMap<String, LiteralCommandNode<S>>,
+ arguments: HashMap<String, ArgumentCommandNode<S>>,
+ pub requirement: Box<dyn Fn(&S) -> bool>,
+ redirect: Option<Box<dyn CommandNodeTrait<S>>>,
+ modifier: Option<Box<dyn RedirectModifier<S>>>,
+ forks: bool,
+ pub command: Option<Box<dyn Command<S>>>,
}
-impl<S> CommandNodeTrait<S> for RootCommandNode<'_, S> {
+impl<S> CommandNodeTrait<S> for RootCommandNode<S> {
fn name(&self) -> &str {
""
}
@@ -63,7 +72,7 @@ impl<S> CommandNodeTrait<S> for RootCommandNode<'_, S> {
}
}
-impl<S> Display for RootCommandNode<'_, S> {
+impl<S> Display for RootCommandNode<S> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "<root>")
}