aboutsummaryrefslogtreecommitdiff
path: root/azalea-brigadier/src/tree
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-04-17 14:02:13 -0500
committermat <github@matdoes.dev>2022-04-17 14:02:13 -0500
commita72a47ced76065caf739898954cd18edbc39174b (patch)
tree5526c7663f253bbd7c8318b9d98413f1f2074852 /azalea-brigadier/src/tree
parent4ff67d4917ce333232189e86aee09f2d82451fc6 (diff)
downloadazalea-drasl-a72a47ced76065caf739898954cd18edbc39174b.tar.xz
Rewrite brigadier
Diffstat (limited to 'azalea-brigadier/src/tree')
-rw-r--r--azalea-brigadier/src/tree/argument_command_node.rs176
-rw-r--r--azalea-brigadier/src/tree/command_node.rs143
-rw-r--r--azalea-brigadier/src/tree/literal_command_node.rs131
-rw-r--r--azalea-brigadier/src/tree/mod.rs4
-rw-r--r--azalea-brigadier/src/tree/root_command_node.rs79
5 files changed, 0 insertions, 533 deletions
diff --git a/azalea-brigadier/src/tree/argument_command_node.rs b/azalea-brigadier/src/tree/argument_command_node.rs
deleted file mode 100644
index 9d2af14e..00000000
--- a/azalea-brigadier/src/tree/argument_command_node.rs
+++ /dev/null
@@ -1,176 +0,0 @@
-use std::{
- any::Any,
- collections::HashMap,
- fmt::{Debug, Display, Formatter},
-};
-
-use crate::{
- arguments::argument_type::ArgumentType,
- builder::required_argument_builder::RequiredArgumentBuilder,
- command::Command,
- context::{
- command_context::CommandContext, command_context_builder::CommandContextBuilder,
- parsed_argument::ParsedArgument,
- },
- exceptions::command_syntax_exception::CommandSyntaxException,
- immutable_string_reader::ImmutableStringReader,
- redirect_modifier::RedirectModifier,
- string_reader::StringReader,
- suggestion::{
- suggestion_provider::SuggestionProvider, suggestions::Suggestions,
- suggestions_builder::SuggestionsBuilder,
- },
-};
-
-use super::{
- command_node::{BaseCommandNode, CommandNodeTrait},
- literal_command_node::LiteralCommandNode,
- root_command_node::RootCommandNode,
-};
-
-const USAGE_ARGUMENT_OPEN: &str = "<";
-const USAGE_ARGUMENT_CLOSE: &str = ">";
-
-pub struct ArgumentCommandNode<S> {
- name: String,
- type_: Box<dyn ArgumentType<Into = dyn Any>>,
- custom_suggestions: Option<Box<dyn SuggestionProvider<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> ArgumentCommandNode<S> {
- fn get_type(&self) -> &dyn ArgumentType<Into = dyn Any> {
- &*self.type_
- }
-
- fn custom_suggestions(&self) -> &Option<Box<dyn SuggestionProvider<S>>> {
- &self.custom_suggestions
- }
-}
-
-impl<S> CommandNodeTrait<S> for ArgumentCommandNode<S> {
- fn name(&self) -> &str {
- &self.name
- }
-
- fn parse(
- &self,
- reader: &mut StringReader,
- context_builder: CommandContextBuilder<S>,
- ) -> Result<(), CommandSyntaxException> {
- // final int start = reader.getCursor();
- // final T result = type.parse(reader);
- // final ParsedArgument<S> parsed = new ParsedArgument<>(start, reader.getCursor(), result);
-
- // contextBuilder.withArgument(name, parsed);
- // contextBuilder.withNode(this, parsed.getRange());
-
- let start = reader.cursor();
- let result = self.get_type().parse(reader)?;
- let parsed = ParsedArgument::new(start, reader.get_cursor(), result);
-
- context_builder.with_argument(&self.name, parsed);
- context_builder.with_node(self, parsed.get_range());
-
- Ok(())
- }
-
- fn list_suggestions(
- &self,
- context: CommandContext<S>,
- builder: &SuggestionsBuilder,
- ) -> Result<Suggestions, CommandSyntaxException> {
- if self.custom_suggestions.is_none() {
- self.get_type().list_suggestions(context, builder)
- } else {
- self.custom_suggestions.get_suggestions(context, builder)
- }
- }
-
- fn is_valid_input(&self, input: &str) -> bool {
- let reader = StringReader::new(input);
- let result = self.get_type().parse(reader);
- if result.is_ok() {
- return !reader.can_read() || reader.peek() == ' ';
- } else {
- return false;
- }
- }
-
- fn usage_text(&self) -> &str {
- USAGE_ARGUMENT_OPEN + self.name + USAGE_ARGUMENT_CLOSE
- }
-
- fn create_builder(&self) -> RequiredArgumentBuilder<S> {
- let builder = RequiredArgumentBuilder::argument(&self.name, &self.type_);
- builder.requires(self.base.get_requirement());
- builder.forward(
- self.base.get_redirect(),
- self.base.get_redirect_modifier(),
- self.base.is_fork(),
- );
- builder.suggests(self.custom_suggestions());
- if self.base.get_command() != None {
- builder.executes(self.base.get_command().unwrap());
- }
- builder
- }
-
- fn get_examples(&self) -> Vec<String> {
- self.type_.get_examples()
- }
-
- fn redirect_modifier(&self) -> Option<&dyn RedirectModifier<S>> {
- self.modifier.as_ref().map(|modifier| modifier.as_ref())
- }
-
- fn can_use(&self, source: S) -> bool {
- (self.requirement)(&source)
- }
-
- fn add_child(&self, node: &Box<dyn CommandNodeTrait<S>>) -> Result<(), String> {
- let dynamic_node = node as &dyn Any;
- if dynamic_node.is::<RootCommandNode<S>>() {
- return Err(String::from(
- "Cannot add a RootCommandNode as a child to any other CommandNode",
- ));
- }
-
- let mut child = self.children.get(node.name());
- if let Some(child) = child {
- // We've found something to merge onto
- if let Some(command) = node.base().command() {
- child.base_mut().command = Some(*command);
- }
- for grandchild in node.base().children().values() {
- child.base_mut().add_child(&*grandchild)?;
- }
- Ok(())
- } else {
- self.children.insert(node.name().to_string(), *node);
-
- if let Some(dynamic_node) = dynamic_node.downcast_ref::<LiteralCommandNode<S>>() {
- self.literals.insert(node.name().to_string(), *dynamic_node);
- } else if let Some(dynamic_node) = dynamic_node.downcast_ref::<ArgumentCommandNode<S>>()
- {
- self.arguments
- .insert(node.name().to_string(), *dynamic_node);
- }
- Ok(())
- }
- }
-}
-
-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
deleted file mode 100644
index 207e114e..00000000
--- a/azalea-brigadier/src/tree/command_node.rs
+++ /dev/null
@@ -1,143 +0,0 @@
-use super::{
- argument_command_node::ArgumentCommandNode, literal_command_node::LiteralCommandNode,
- root_command_node::RootCommandNode,
-};
-use crate::{
- arguments::argument_type::ArgumentType,
- builder::argument_builder::ArgumentBuilder,
- command::Command,
- context::{command_context::CommandContext, command_context_builder::CommandContextBuilder},
- exceptions::command_syntax_exception::CommandSyntaxException,
- redirect_modifier::RedirectModifier,
- string_reader::StringReader,
- suggestion::{suggestions::Suggestions, suggestions_builder::SuggestionsBuilder},
-};
-use std::ops::Deref;
-use std::{any::Any, collections::HashMap, fmt::Debug};
-
-#[enum_dispatch(CommandNodeTrait)]
-enum CommandNodeEnum<S> {
- Literal(LiteralCommandNode<S>),
- Argument(ArgumentCommandNode<S>),
- Root(RootCommandNode<S>),
-}
-
-impl<S> CommandNodeEnum<S> {
- fn redirect_modifier(&self) -> Option<&dyn RedirectModifier<S>> {
- (*self).modifier.as_ref().map(|modifier| modifier.as_ref())
- }
-
- fn can_use(&self, source: S) -> bool {
- (self.requirement)(&source)
- }
-
- fn add_child(&self, node: &Box<dyn CommandNodeTrait<S>>) -> Result<(), String> {
- let dynamic_node = node as &dyn Any;
- if dynamic_node.is::<RootCommandNode<S>>() {
- return Err(String::from(
- "Cannot add a RootCommandNode as a child to any other CommandNode",
- ));
- }
-
- let mut child = self.children.get(node.name());
- if let Some(child) = child {
- // We've found something to merge onto
- if let Some(command) = node.base().command() {
- child.base_mut().command = Some(*command);
- }
- for grandchild in node.base().children().values() {
- child.base_mut().add_child(&*grandchild)?;
- }
- Ok(())
- } else {
- self.children.insert(node.name().to_string(), *node);
-
- if let Some(dynamic_node) = dynamic_node.downcast_ref::<LiteralCommandNode<S>>() {
- self.literals.insert(node.name().to_string(), *dynamic_node);
- } else if let Some(dynamic_node) = dynamic_node.downcast_ref::<ArgumentCommandNode<S>>()
- {
- self.arguments
- .insert(node.name().to_string(), *dynamic_node);
- }
- Ok(())
- }
- }
-}
-pub struct BaseCommandNode<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> Clone for BaseCommandNode<'_, S> {
-// fn clone(&self) -> Self {
-// Self {
-// children: self.children.clone(),
-// literals: self.literals.clone(),
-// arguments: self.arguments.clone(),
-// requirement: self.requirement.clone(),
-// redirect: self.redirect.clone(),
-// modifier: self.modifier.clone(),
-// forks: self.forks.clone(),
-// command: self.command.clone(),
-// }
-// }
-// }
-
-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)
- .field("literals", &self.literals)
- .field("arguments", &self.arguments)
- .field("requirement", &self.requirement)
- .field("redirect", &self.redirect)
- .field("modifier", &self.modifier)
- .field("forks", &self.forks)
- .field("command", &self.command)
- .finish()
- }
-}
-
-impl<S> Default for BaseCommandNode<S> {
- fn default() -> Self {
- Self {
- children: HashMap::new(),
- literals: HashMap::new(),
- arguments: HashMap::new(),
- requirement: Box::new(|_| true),
- redirect: None,
- modifier: None,
- forks: false,
- command: None,
- }
- }
-}
-
-#[enum_dispatch]
-pub trait CommandNodeTrait<S> {
- fn name(&self) -> &str;
- fn usage_text(&self) -> &str;
- fn parse(
- &self,
- reader: &mut StringReader,
- context_builder: CommandContextBuilder<S>,
- ) -> Result<(), CommandSyntaxException>;
- fn list_suggestions(
- &self,
- context: CommandContext<S>,
- builder: &SuggestionsBuilder,
- ) -> Result<Suggestions, CommandSyntaxException>;
- 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
deleted file mode 100644
index 2db31d97..00000000
--- a/azalea-brigadier/src/tree/literal_command_node.rs
+++ /dev/null
@@ -1,131 +0,0 @@
-use crate::{
- arguments::argument_type::ArgumentType,
- 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::{collections::HashMap, fmt::Debug};
-
-use super::{
- argument_command_node::ArgumentCommandNode,
- command_node::{BaseCommandNode, CommandNodeTrait},
-};
-
-#[derive(Debug, Clone)]
-pub struct LiteralCommandNode<S> {
- literal: String,
- literal_lowercase: String,
-
- 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> LiteralCommandNode<S> {
- pub fn new(literal: String) -> Self {
- let literal_lowercase = literal.to_lowercase();
- Self {
- literal,
- literal_lowercase,
- ..Default::default()
- }
- }
-
- pub fn literal(&self) -> &String {
- &self.literal
- }
-
- pub fn parse(&self, reader: &mut StringReader) -> i32 {
- let start = reader.cursor();
- if reader.can_read_length(self.literal.len()) {
- let end = start + self.literal.len();
- if reader.string()[start..end].eq(&self.literal) {
- reader.cursor = end;
- if !reader.can_read() || reader.peek() == ' ' {
- return end as i32;
- } else {
- reader.cursor = start;
- }
- }
- }
- -1
- }
-}
-
-impl<S> CommandNodeTrait<S> for LiteralCommandNode<S> {
- fn name(&self) -> &str {
- &self.literal
- }
-
- fn parse(
- &self,
- reader: &mut StringReader<'_>,
- context_builder: CommandContextBuilder<S>,
- ) -> Result<(), CommandSyntaxException> {
- let start = reader.cursor();
- let end = self.parse(reader);
- if end > -1 {
- return Ok(());
- }
-
- Err(BuiltInExceptions::LiteralIncorrect {
- expected: self.literal().to_string(),
- }
- .create_with_context(reader))
- }
-
- fn list_suggestions(
- &self,
- context: CommandContext<S>,
- builder: &SuggestionsBuilder,
- ) -> Result<Suggestions, CommandSyntaxException> {
- if self
- .literal_lowercase
- .starts_with(&builder.remaining_lowercase())
- {
- Ok(builder.suggest(self.literal()).build())
- } else {
- Ok(Suggestions::default())
- }
- }
-
- fn is_valid_input(&self, input: &str) -> bool {
- self.parse(&mut StringReader::from(input)) > -1
- }
-
- fn usage_text(&self) -> &str {
- &self.literal
- }
-
- fn create_builder(&self) -> Box<dyn ArgumentBuilder<S>> {
- let mut builder = LiteralArgumentBuilder::literal(self.literal().to_string());
- builder.base.requires(&self.base().requirement);
- builder.base.forward(
- self.base.redirect(),
- self.base.redirect_modifier(),
- self.base.is_fork(),
- );
- if self.command().is_some() {
- builder.executes(self.command().unwrap());
- }
- builder
- }
-
- fn get_examples(&self) -> Vec<String> {
- todo!()
- }
-}
diff --git a/azalea-brigadier/src/tree/mod.rs b/azalea-brigadier/src/tree/mod.rs
deleted file mode 100644
index 3dc22583..00000000
--- a/azalea-brigadier/src/tree/mod.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-pub mod argument_command_node;
-pub mod command_node;
-pub mod literal_command_node;
-pub mod root_command_node;
diff --git a/azalea-brigadier/src/tree/root_command_node.rs b/azalea-brigadier/src/tree/root_command_node.rs
deleted file mode 100644
index 6b8bc157..00000000
--- a/azalea-brigadier/src/tree/root_command_node.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-use super::{
- argument_command_node::ArgumentCommandNode,
- command_node::{BaseCommandNode, CommandNodeTrait},
- literal_command_node::LiteralCommandNode,
-};
-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,
- },
- redirect_modifier::RedirectModifier,
- string_reader::StringReader,
- suggestion::{suggestions::Suggestions, suggestions_builder::SuggestionsBuilder},
-};
-use std::{
- any::Any,
- collections::HashMap,
- fmt::{Debug, Display, Formatter},
-};
-
-#[derive(Default)]
-pub struct RootCommandNode<S> {
- // Since Rust doesn't have extending, we put the struct this is extending as the "base" field
- 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> {
- fn name(&self) -> &str {
- ""
- }
-
- fn parse(
- &self,
- reader: &mut StringReader<'_>,
- context_builder: CommandContextBuilder<S>,
- ) -> Result<(), CommandSyntaxException> {
- Ok(())
- }
-
- fn list_suggestions(
- &self,
- context: CommandContext<S>,
- builder: &SuggestionsBuilder,
- ) -> Result<Suggestions, CommandSyntaxException> {
- Ok(Suggestions::default())
- }
-
- fn is_valid_input(&self, input: &str) -> bool {
- false
- }
-
- fn usage_text(&self) -> &str {
- ""
- }
-
- fn create_builder(&self) -> Box<dyn ArgumentBuilder<S>> {
- panic!("Cannot convert root into a builder");
- }
-
- fn get_examples(&self) -> Vec<String> {
- vec![]
- }
-}
-
-impl<S> Display for RootCommandNode<S> {
- fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
- write!(f, "<root>")
- }
-}