aboutsummaryrefslogtreecommitdiff
path: root/azalea-brigadier/src
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-04-17 15:57:28 -0500
committermat <github@matdoes.dev>2022-04-17 15:57:28 -0500
commit2e904225611b66fa72b082e4f5e188b55b333fcd (patch)
tree5def0247b2a721ea20eded8ac996d957c591a403 /azalea-brigadier/src
parent10cd1733cbba5c637fa0130a0cd7a7ab6e618226 (diff)
downloadazalea-drasl-2e904225611b66fa72b082e4f5e188b55b333fcd.tar.xz
Fix clippy issues and add a couple tests to dispatcher
Diffstat (limited to 'azalea-brigadier/src')
-rw-r--r--azalea-brigadier/src/builder/argument_builder.rs8
-rw-r--r--azalea-brigadier/src/builder/literal_argument_builder.rs9
-rw-r--r--azalea-brigadier/src/builder/required_argument_builder.rs7
-rw-r--r--azalea-brigadier/src/context.rs10
-rw-r--r--azalea-brigadier/src/dispatcher.rs132
-rw-r--r--azalea-brigadier/src/exceptions/command_syntax_exception.rs9
-rw-r--r--azalea-brigadier/src/message.rs2
-rw-r--r--azalea-brigadier/src/parsers.rs6
-rw-r--r--azalea-brigadier/src/string_reader.rs18
-rw-r--r--azalea-brigadier/src/tree.rs33
10 files changed, 158 insertions, 76 deletions
diff --git a/azalea-brigadier/src/builder/argument_builder.rs b/azalea-brigadier/src/builder/argument_builder.rs
index 17e9d625..6f23457a 100644
--- a/azalea-brigadier/src/builder/argument_builder.rs
+++ b/azalea-brigadier/src/builder/argument_builder.rs
@@ -41,21 +41,21 @@ impl<S: Any + Clone> ArgumentBuilder<S> {
}
}
- pub fn then(&mut self, node: ArgumentBuilder<S>) -> &mut Self {
+ pub fn then(&mut self, node: ArgumentBuilder<S>) -> Self {
let built_node = node.build();
let name = built_node.name();
let node_reference = Rc::new(RefCell::new(built_node.clone()));
self.children
.insert(name.to_string(), node_reference.clone());
match &built_node.value {
- ArgumentBuilderType::Literal(literal) => {
+ ArgumentBuilderType::Literal(_) => {
self.literals.insert(name.to_string(), node_reference);
}
- ArgumentBuilderType::Argument(argument) => {
+ ArgumentBuilderType::Argument(_) => {
self.arguments.insert(name.to_string(), node_reference);
}
}
- self
+ self.clone()
}
pub fn executes<F>(&mut self, f: F) -> Self
diff --git a/azalea-brigadier/src/builder/literal_argument_builder.rs b/azalea-brigadier/src/builder/literal_argument_builder.rs
index d8898540..e5e165d8 100644
--- a/azalea-brigadier/src/builder/literal_argument_builder.rs
+++ b/azalea-brigadier/src/builder/literal_argument_builder.rs
@@ -1,14 +1,5 @@
use std::any::Any;
-use crate::{
- context::CommandContextBuilder,
- exceptions::{
- builtin_exceptions::BuiltInExceptions, command_syntax_exception::CommandSyntaxException,
- },
- string_range::StringRange,
- string_reader::StringReader,
-};
-
use super::argument_builder::{ArgumentBuilder, ArgumentBuilderType};
#[derive(Debug, Clone, Default)]
diff --git a/azalea-brigadier/src/builder/required_argument_builder.rs b/azalea-brigadier/src/builder/required_argument_builder.rs
index 9cd089de..0eb5d11a 100644
--- a/azalea-brigadier/src/builder/required_argument_builder.rs
+++ b/azalea-brigadier/src/builder/required_argument_builder.rs
@@ -16,7 +16,7 @@ impl Argument {
pub fn new(name: &str, parser: Rc<dyn Parser>) -> Self {
Self {
name: name.to_string(),
- parser: parser,
+ parser,
}
}
@@ -41,9 +41,6 @@ impl Debug for Argument {
}
/// Shortcut for creating a new argument builder node.
-pub fn argument<'a, S: Any + Clone>(
- name: &'a str,
- parser: impl Parser + 'static,
-) -> ArgumentBuilder<S> {
+pub fn argument<S: Any + Clone>(name: &str, parser: impl Parser + 'static) -> ArgumentBuilder<S> {
ArgumentBuilder::new(Argument::new(name, Rc::new(parser)).into())
}
diff --git a/azalea-brigadier/src/context.rs b/azalea-brigadier/src/context.rs
index a68c1da5..5ffe2028 100644
--- a/azalea-brigadier/src/context.rs
+++ b/azalea-brigadier/src/context.rs
@@ -1,4 +1,4 @@
-use std::{any::Any, cell::RefCell, collections::HashMap, fmt::Debug, ptr, rc::Rc};
+use std::{any::Any, cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc};
use crate::{
dispatcher::CommandDispatcher, modifier::RedirectModifier, string_range::StringRange,
@@ -73,7 +73,7 @@ impl<S: Any + Clone> CommandContextBuilder<S> {
nodes: self.nodes.clone(),
source: self.source.clone(),
command: self.command.clone(),
- child: self.child.clone().map(|c| Rc::new(c.build(&input))),
+ child: self.child.clone().map(|c| Rc::new(c.build(input))),
range: self.range.clone(),
forks: self.forks,
modifier: self.modifier.clone(),
@@ -125,7 +125,7 @@ impl<S: Any + Clone> CommandContext<S> {
if Rc::ptr_eq(&source, &self.source) {
return self.clone();
}
- return CommandContext {
+ CommandContext {
source,
input: self.input.clone(),
arguments: self.arguments.clone(),
@@ -136,11 +136,11 @@ impl<S: Any + Clone> CommandContext<S> {
child: self.child.clone(),
modifier: self.modifier.clone(),
forks: self.forks,
- };
+ }
}
pub fn has_nodes(&self) -> bool {
- return !self.nodes.is_empty();
+ !self.nodes.is_empty()
}
pub fn argument(&self, name: &str) -> Option<Rc<dyn Any>> {
diff --git a/azalea-brigadier/src/dispatcher.rs b/azalea-brigadier/src/dispatcher.rs
index b2004859..029f0ed0 100644
--- a/azalea-brigadier/src/dispatcher.rs
+++ b/azalea-brigadier/src/dispatcher.rs
@@ -75,16 +75,14 @@ impl<S: Any + Clone> CommandDispatcher<S> {
reader.cursor = cursor;
continue;
}
- if reader.can_read() {
- if reader.peek() != ' ' {
- errors.insert(
- Rc::new((*child.borrow()).clone()),
- BuiltInExceptions::DispatcherExpectedArgumentSeparator
- .create_with_context(&reader),
- );
- reader.cursor = cursor;
- continue;
- }
+ if reader.can_read() && reader.peek() != ' ' {
+ errors.insert(
+ Rc::new((*child.borrow()).clone()),
+ BuiltInExceptions::DispatcherExpectedArgumentSeparator
+ .create_with_context(&reader),
+ );
+ reader.cursor = cursor;
+ continue;
}
context.with_command(&child.borrow().command);
@@ -120,7 +118,7 @@ impl<S: Any + Clone> CommandDispatcher<S> {
}
}
- if potentials.len() > 0 {
+ if !potentials.is_empty() {
if potentials.len() > 1 {
potentials.sort_by(|a, b| {
if !a.reader.can_read() && b.reader.can_read() {
@@ -174,11 +172,11 @@ impl<S: Any + Clone> CommandDispatcher<S> {
let mut forked = false;
let mut found_command = false;
let command = parse.reader.string();
- let original = parse.context.build(&command);
+ let original = parse.context.build(command);
let mut contexts = vec![original];
let mut next: Vec<CommandContext<S>> = vec![];
- while contexts.len() > 0 {
+ while !contexts.is_empty() {
for context in contexts.iter() {
let child = &context.child;
if let Some(child) = child {
@@ -239,3 +237,111 @@ impl<S: Any + Clone> Clone for CommandDispatcher<S> {
}
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::builder::literal_argument_builder::literal;
+
+ struct CommandSource {}
+
+ fn input_with_offset(input: &str, offset: usize) -> StringReader {
+ let mut result: StringReader = input.into();
+ result.cursor = offset;
+ result
+ }
+
+ // @Test
+ // public void testCreateAndExecuteCommand() throws Exception {
+ // subject.register(literal("foo").executes(command));
+
+ // assertThat(subject.execute("foo", source), is(42));
+ // verify(command).run(any(CommandContext.class));
+ // }
+ #[test]
+ fn create_and_execute_command() {
+ let mut subject = CommandDispatcher::<Rc<CommandSource>>::new();
+ subject.register(literal("foo").executes(|_| 42));
+
+ assert_eq!(
+ subject
+ .execute("foo".into(), Rc::new(CommandSource {}))
+ .unwrap(),
+ 42
+ );
+ }
+ // @Test
+ // public void testCreateAndExecuteOffsetCommand() throws Exception {
+ // subject.register(literal("foo").executes(command));
+
+ // assertThat(subject.execute(inputWithOffset("/foo", 1), source), is(42));
+ // verify(command).run(any(CommandContext.class));
+ // }
+ #[test]
+ fn create_and_execute_offset_command() {
+ let mut subject = CommandDispatcher::<Rc<CommandSource>>::new();
+ subject.register(literal("foo").executes(|_| 42));
+
+ assert_eq!(
+ subject
+ .execute(input_with_offset("/foo", 1), Rc::new(CommandSource {}))
+ .unwrap(),
+ 42
+ );
+ }
+ // @Test
+ // public void testCreateAndMergeCommands() throws Exception {
+ // subject.register(literal("base").then(literal("foo").executes(command)));
+ // subject.register(literal("base").then(literal("bar").executes(command)));
+
+ // assertThat(subject.execute("base foo", source), is(42));
+ // assertThat(subject.execute("base bar", source), is(42));
+ // verify(command, times(2)).run(any(CommandContext.class));
+ // }
+ #[test]
+ fn create_and_merge_commands() {
+ let mut subject = CommandDispatcher::<Rc<CommandSource>>::new();
+ subject.register(literal("base").then(literal("foo").executes(|_| 42)));
+ subject.register(literal("base").then(literal("bar").executes(|_| 42)));
+
+ assert_eq!(
+ subject
+ .execute("base foo".into(), Rc::new(CommandSource {}))
+ .unwrap(),
+ 42
+ );
+ assert_eq!(
+ subject
+ .execute("base bar".into(), Rc::new(CommandSource {}))
+ .unwrap(),
+ 42
+ );
+ }
+ // @Test
+ // public void testExecuteUnknownCommand() throws Exception {
+ // subject.register(literal("bar"));
+ // subject.register(literal("baz"));
+
+ // try {
+ // subject.execute("foo", source);
+ // fail();
+ // } catch (final CommandSyntaxException ex) {
+ // assertThat(ex.getType(), is(CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand()));
+ // assertThat(ex.getCursor(), is(0));
+ // }
+ // }
+ // #[test]
+ // fn execute_unknown_command() {
+ // let mut subject = CommandDispatcher::<Rc<CommandSource>>::new();
+ // subject.register(literal("bar"));
+ // subject.register(literal("baz"));
+
+ // assert_eq!(
+ // subject
+ // .execute("foo".into(), Rc::new(CommandSource {}))
+ // .err()
+ // .unwrap(),
+ // BuiltInExceptions::DispatcherUnknownCommand.create()
+ // );
+ // }
+}
diff --git a/azalea-brigadier/src/exceptions/command_syntax_exception.rs b/azalea-brigadier/src/exceptions/command_syntax_exception.rs
index 6cd4e53d..93ac788c 100644
--- a/azalea-brigadier/src/exceptions/command_syntax_exception.rs
+++ b/azalea-brigadier/src/exceptions/command_syntax_exception.rs
@@ -1,9 +1,9 @@
-use std::{cmp, fmt, rc::Rc};
+use std::{cmp, fmt};
use super::builtin_exceptions::BuiltInExceptions;
use crate::message::Message;
-#[derive(Clone)]
+#[derive(Clone, PartialEq)]
pub struct CommandSyntaxException {
type_: BuiltInExceptions,
message: Message,
@@ -12,7 +12,6 @@ pub struct CommandSyntaxException {
}
const CONTEXT_AMOUNT: usize = 10;
-const ENABLE_COMMAND_STACK_TRACES: bool = true;
impl CommandSyntaxException {
pub fn new(type_: BuiltInExceptions, message: Message, input: &str, cursor: usize) -> Self {
@@ -76,8 +75,8 @@ impl CommandSyntaxException {
&self.type_
}
- pub fn input(&self) -> String {
- self.input()
+ pub fn input(&self) -> &Option<String> {
+ &self.input
}
pub fn cursor(&self) -> Option<usize> {
diff --git a/azalea-brigadier/src/message.rs b/azalea-brigadier/src/message.rs
index 9d133c7e..75e07d4e 100644
--- a/azalea-brigadier/src/message.rs
+++ b/azalea-brigadier/src/message.rs
@@ -1,5 +1,3 @@
-use std::rc::Rc;
-
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct Message(String);
diff --git a/azalea-brigadier/src/parsers.rs b/azalea-brigadier/src/parsers.rs
index bdf34438..77e57ace 100644
--- a/azalea-brigadier/src/parsers.rs
+++ b/azalea-brigadier/src/parsers.rs
@@ -1,4 +1,4 @@
-use std::{any::Any, marker::PhantomData, rc::Rc};
+use std::{any::Any, rc::Rc};
use crate::{
context::CommandContext,
@@ -24,6 +24,7 @@ impl Parser for Integer {
let result = reader.read_int()?;
if let Some(minimum) = self.minimum {
if result < minimum {
+ reader.cursor = start;
return Err(BuiltInExceptions::IntegerTooSmall {
found: result,
min: minimum,
@@ -33,6 +34,7 @@ impl Parser for Integer {
}
if let Some(maximum) = self.maximum {
if result > maximum {
+ reader.cursor = start;
return Err(BuiltInExceptions::IntegerTooBig {
found: result,
max: maximum,
@@ -52,5 +54,5 @@ pub fn get_integer<S: Any + Clone>(context: &CommandContext<S>, name: &str) -> O
.argument(name)
.unwrap()
.downcast_ref::<i32>()
- .map(|x| *x)
+ .copied()
}
diff --git a/azalea-brigadier/src/string_reader.rs b/azalea-brigadier/src/string_reader.rs
index 403b8e99..5825871f 100644
--- a/azalea-brigadier/src/string_reader.rs
+++ b/azalea-brigadier/src/string_reader.rs
@@ -1,7 +1,7 @@
use crate::exceptions::{
builtin_exceptions::BuiltInExceptions, command_syntax_exception::CommandSyntaxException,
};
-use std::{rc::Rc, str::FromStr};
+use std::str::FromStr;
#[derive(Clone)]
pub struct StringReader {
@@ -79,7 +79,7 @@ impl StringReader {
}
pub fn is_allowed_number(c: char) -> bool {
- c >= '0' && c <= '9' || c == '.' || c == '-'
+ ('0'..='9').contains(&c) || c == '.' || c == '-'
}
pub fn is_quoted_string_start(c: char) -> bool {
@@ -177,9 +177,9 @@ impl StringReader {
}
pub fn is_allowed_in_unquoted_string(c: char) -> bool {
- c >= '0' && c <= '9'
- || c >= 'A' && c <= 'Z'
- || c >= 'a' && c <= 'z'
+ ('0'..='9').contains(&c)
+ || ('A'..='Z').contains(&c)
+ || ('a'..='z').contains(&c)
|| c == '_'
|| c == '-'
|| c == '.'
@@ -232,7 +232,7 @@ impl StringReader {
}
}
- return Err(BuiltInExceptions::ReaderExpectedEndOfQuote.create_with_context(self));
+ Err(BuiltInExceptions::ReaderExpectedEndOfQuote.create_with_context(self))
}
pub fn read_string(&mut self) -> Result<String, CommandSyntaxException> {
@@ -255,12 +255,12 @@ impl StringReader {
}
if value == "true" {
- return Ok(true);
+ Ok(true)
} else if value == "false" {
- return Ok(false);
+ Ok(false)
} else {
self.cursor = start;
- return Err(BuiltInExceptions::ReaderInvalidBool { value }.create_with_context(self));
+ Err(BuiltInExceptions::ReaderInvalidBool { value }.create_with_context(self))
}
}
diff --git a/azalea-brigadier/src/tree.rs b/azalea-brigadier/src/tree.rs
index c81c599f..5c33a879 100644
--- a/azalea-brigadier/src/tree.rs
+++ b/azalea-brigadier/src/tree.rs
@@ -11,15 +11,7 @@ use crate::{
string_range::StringRange,
string_reader::StringReader,
};
-use std::{
- any::Any,
- cell::RefCell,
- collections::{BTreeMap, HashMap},
- fmt::Debug,
- hash::Hash,
- ptr,
- rc::Rc,
-};
+use std::{any::Any, cell::RefCell, collections::BTreeMap, fmt::Debug, hash::Hash, ptr, rc::Rc};
/// An ArgumentBuilder that has been built.
#[derive(Clone)]
@@ -67,7 +59,7 @@ impl<S: Any + Clone> CommandNode<S> {
pub fn get_relevant_nodes(&self, input: &mut StringReader) -> Vec<Rc<RefCell<CommandNode<S>>>> {
let literals = self.literals();
- if literals.len() > 0 {
+ if !literals.is_empty() {
let cursor = input.cursor();
while input.can_read() && input.peek() != ' ' {
input.skip();
@@ -83,18 +75,10 @@ impl<S: Any + Clone> CommandNode<S> {
if let Some(literal) = literal {
return vec![literal.clone()];
} else {
- return self
- .arguments()
- .values()
- .map(|argument| argument.clone())
- .collect();
+ return self.arguments().values().cloned().collect();
}
} else {
- return self
- .arguments()
- .values()
- .map(|argument| argument.clone())
- .collect();
+ self.arguments().values().cloned().collect()
}
}
@@ -147,7 +131,7 @@ impl<S: Any + Clone> CommandNode<S> {
.expect("Couldn't get result for some reason");
let parsed = ParsedArgument {
range: StringRange::between(start, reader.cursor()),
- result: result,
+ result,
};
context_builder.with_argument(&argument.name, parsed.clone());
@@ -175,7 +159,7 @@ impl<S: Any + Clone> CommandNode<S> {
fn parse(&self, reader: &mut StringReader) -> Option<usize> {
match self.value {
- ArgumentBuilderType::Argument(ref argument) => {
+ ArgumentBuilderType::Argument(_) => {
panic!("Can't parse argument.")
}
ArgumentBuilderType::Literal(ref literal) => {
@@ -252,7 +236,9 @@ impl<S: Any + Clone> PartialEq for CommandNode<S> {
return false;
}
if let Some(selfexecutes) = &self.command {
+ // idk how to do this better since we can't compare `dyn Fn`s
if let Some(otherexecutes) = &other.command {
+ #[allow(clippy::vtable_address_comparisons)]
if !Rc::ptr_eq(selfexecutes, otherexecutes) {
return false;
}
@@ -260,6 +246,9 @@ impl<S: Any + Clone> PartialEq for CommandNode<S> {
return false;
}
}
+ else if other.command.is_some() {
+ return false;
+ }
true
}
}