aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xazalea-brigadier/README.md21
-rw-r--r--azalea-brigadier/src/arguments/double_argument_type.rs2
-rw-r--r--azalea-brigadier/src/arguments/float_argument_type.rs2
-rw-r--r--azalea-brigadier/src/arguments/long_argument_type.rs2
-rwxr-xr-xazalea-brigadier/src/builder/argument_builder.rs41
-rwxr-xr-xazalea-brigadier/src/command_dispatcher.rs27
-rwxr-xr-xazalea-brigadier/src/lib.rs7
-rwxr-xr-xazalea-brigadier/tests/command_dispatcher_test.rs82
8 files changed, 114 insertions, 70 deletions
diff --git a/azalea-brigadier/README.md b/azalea-brigadier/README.md
index c5aff629..6e573c8b 100755
--- a/azalea-brigadier/README.md
+++ b/azalea-brigadier/README.md
@@ -4,4 +4,23 @@ A Rust port of Mojang's [Brigadier](https://github.com/Mojang/brigadier) command
# Examples
-See the [tests](https://github.com/mat-1/azalea/tree/main/azalea-brigadier/tests).
+```rust
+use azalea_brigadier::prelude::*;
+use std::sync::Arc;
+
+#[derive(Debug, PartialEq)]
+struct CommandSource {}
+
+let mut subject = CommandDispatcher::new();
+subject.register(literal("foo").executes(|_| 42));
+
+assert_eq!(
+ subject
+ .execute("foo", Arc::new(CommandSource {}))
+ .unwrap(),
+ 42
+);
+```
+
+See the [tests](https://github.com/mat-1/azalea/tree/main/azalea-brigadier/tests) for more.
+
diff --git a/azalea-brigadier/src/arguments/double_argument_type.rs b/azalea-brigadier/src/arguments/double_argument_type.rs
index 117a11cc..d83bfb2a 100644
--- a/azalea-brigadier/src/arguments/double_argument_type.rs
+++ b/azalea-brigadier/src/arguments/double_argument_type.rs
@@ -45,7 +45,7 @@ impl ArgumentType for Double {
pub fn double() -> impl ArgumentType {
Double::default()
}
-pub fn get_integer<S>(context: &CommandContext<S>, name: &str) -> Option<f64> {
+pub fn get_double<S>(context: &CommandContext<S>, name: &str) -> Option<f64> {
context
.argument(name)
.unwrap()
diff --git a/azalea-brigadier/src/arguments/float_argument_type.rs b/azalea-brigadier/src/arguments/float_argument_type.rs
index f335f11a..0d194efe 100644
--- a/azalea-brigadier/src/arguments/float_argument_type.rs
+++ b/azalea-brigadier/src/arguments/float_argument_type.rs
@@ -45,7 +45,7 @@ impl ArgumentType for Float {
pub fn float() -> impl ArgumentType {
Float::default()
}
-pub fn get_integer<S>(context: &CommandContext<S>, name: &str) -> Option<f32> {
+pub fn get_float<S>(context: &CommandContext<S>, name: &str) -> Option<f32> {
context
.argument(name)
.unwrap()
diff --git a/azalea-brigadier/src/arguments/long_argument_type.rs b/azalea-brigadier/src/arguments/long_argument_type.rs
index 435dd92a..9b3469b6 100644
--- a/azalea-brigadier/src/arguments/long_argument_type.rs
+++ b/azalea-brigadier/src/arguments/long_argument_type.rs
@@ -45,7 +45,7 @@ impl ArgumentType for Long {
pub fn long() -> impl ArgumentType {
Long::default()
}
-pub fn get_integer<S>(context: &CommandContext<S>, name: &str) -> Option<i64> {
+pub fn get_long<S>(context: &CommandContext<S>, name: &str) -> Option<i64> {
context
.argument(name)
.unwrap()
diff --git a/azalea-brigadier/src/builder/argument_builder.rs b/azalea-brigadier/src/builder/argument_builder.rs
index c6f2146a..643a3bd0 100755
--- a/azalea-brigadier/src/builder/argument_builder.rs
+++ b/azalea-brigadier/src/builder/argument_builder.rs
@@ -43,15 +43,38 @@ impl<S> ArgumentBuilder<S> {
}
}
+ /// Continue building this node with a child node.
+ ///
+ /// ```
+ /// # use azalea_brigadier::prelude::*;
+ /// # let mut subject = CommandDispatcher::<()>::new();
+ /// literal("foo").then(
+ /// literal("bar").executes(|ctx: &CommandContext<()>| 42)
+ /// )
+ /// # ;
+ /// ```
pub fn then(self, argument: ArgumentBuilder<S>) -> Self {
self.then_built(argument.build())
}
+ /// Add an already built child node to this node.
+ ///
+ /// You should usually use [`Self::then`] instead.
pub fn then_built(mut self, argument: CommandNode<S>) -> Self {
self.arguments.add_child(&Arc::new(RwLock::new(argument)));
self
}
+ /// Set the command to be executed when this node is reached. If this is not
+ /// present on a node, it is not a valid command.
+ ///
+ /// ```
+ /// # use azalea_brigadier::prelude::*;
+ /// # let mut subject = CommandDispatcher::<()>::new();
+ /// # subject.register(
+ /// literal("foo").executes(|ctx: &CommandContext<()>| 42)
+ /// # );
+ /// ```
pub fn executes<F>(mut self, f: F) -> Self
where
F: Fn(&CommandContext<S>) -> i32 + Send + Sync + 'static,
@@ -60,6 +83,22 @@ impl<S> ArgumentBuilder<S> {
self
}
+ /// Set the requirement for this node to be considered. If this is not
+ /// present on a node, it is considered to always pass.
+ ///
+ /// ```
+ /// # use azalea_brigadier::prelude::*;
+ /// # use std::sync::Arc;
+ /// # pub struct CommandSource {
+ /// # pub opped: bool,
+ /// # }
+ /// # let mut subject = CommandDispatcher::<CommandSource>::new();
+ /// # subject.register(
+ /// literal("foo")
+ /// .requires(|s: Arc<CommandSource>| s.opped)
+ /// // ...
+ /// # .executes(|ctx: &CommandContext<CommandSource>| 42)
+ /// # );
pub fn requires<F>(mut self, requirement: F) -> Self
where
F: Fn(Arc<S>) -> bool + Send + Sync + 'static,
@@ -95,6 +134,8 @@ impl<S> ArgumentBuilder<S> {
self
}
+ /// Manually build this node into a [`CommandNode`]. You probably don't need
+ /// to do this yourself.
pub fn build(self) -> CommandNode<S> {
let mut result = CommandNode {
value: self.arguments.value,
diff --git a/azalea-brigadier/src/command_dispatcher.rs b/azalea-brigadier/src/command_dispatcher.rs
index a14b5009..595bc57d 100755
--- a/azalea-brigadier/src/command_dispatcher.rs
+++ b/azalea-brigadier/src/command_dispatcher.rs
@@ -11,6 +11,12 @@ use crate::{
use std::{cmp::Ordering, collections::HashMap, mem, rc::Rc, sync::Arc};
/// The root of the command tree. You need to make this to register commands.
+///
+/// ```
+/// # use azalea_brigadier::prelude::*;
+/// # struct CommandSource;
+/// let mut subject = CommandDispatcher::<CommandSource>::new();
+/// ```
pub struct CommandDispatcher<S>
where
Self: Sync + Send,
@@ -25,13 +31,22 @@ impl<S> CommandDispatcher<S> {
}
}
+ /// Add a new node to the root.
+ ///
+ /// ```
+ /// # use azalea_brigadier::prelude::*;
+ /// # let mut subject = CommandDispatcher::<()>::new();
+ /// subject.register(literal("foo").executes(|_| 42));
+ /// ```
pub fn register(&mut self, node: ArgumentBuilder<S>) -> Arc<RwLock<CommandNode<S>>> {
let build = Arc::new(RwLock::new(node.build()));
self.root.write().add_child(&build);
build
}
- pub fn parse(&self, command: StringReader, source: Arc<S>) -> ParseResults<S> {
+ pub fn parse(&self, command: StringReader, source: S) -> ParseResults<S> {
+ let source = Arc::new(source);
+
let context = CommandContextBuilder::new(self, source, self.root.clone(), command.cursor());
self.parse_nodes(&self.root, &command, context).unwrap()
}
@@ -140,11 +155,17 @@ impl<S> CommandDispatcher<S> {
})
}
+ /// Parse and execute the command using the given input and context. The
+ /// number returned depends on the command, and may not be of significance.
+ ///
+ /// This is a shortcut for `Self::parse` and `Self::execute_parsed`.
pub fn execute(
&self,
- input: StringReader,
- source: Arc<S>,
+ input: impl Into<StringReader>,
+ source: S,
) -> Result<i32, CommandSyntaxException> {
+ let input = input.into();
+
let parse = self.parse(input, source);
Self::execute_parsed(parse)
}
diff --git a/azalea-brigadier/src/lib.rs b/azalea-brigadier/src/lib.rs
index 8b8e116e..161ef83a 100755
--- a/azalea-brigadier/src/lib.rs
+++ b/azalea-brigadier/src/lib.rs
@@ -14,8 +14,11 @@ pub mod tree;
pub mod prelude {
pub use crate::{
arguments::{
- double_argument_type::double, float_argument_type::float,
- integer_argument_type::integer, long_argument_type::long, string_argument_type::string,
+ double_argument_type::{double, get_double},
+ float_argument_type::{float, get_float},
+ integer_argument_type::{get_integer, integer},
+ long_argument_type::{get_long, long},
+ string_argument_type::{get_string, greedy_string, string, word},
},
builder::{literal_argument_builder::literal, required_argument_builder::argument},
command_dispatcher::CommandDispatcher,
diff --git a/azalea-brigadier/tests/command_dispatcher_test.rs b/azalea-brigadier/tests/command_dispatcher_test.rs
index 4479cfa2..eecbf668 100755
--- a/azalea-brigadier/tests/command_dispatcher_test.rs
+++ b/azalea-brigadier/tests/command_dispatcher_test.rs
@@ -19,26 +19,13 @@ fn input_with_offset(input: &str, offset: usize) -> StringReader {
}
#[test]
-fn create_and_execute_command() {
- let mut subject = CommandDispatcher::new();
- subject.register(literal("foo").executes(|_| 42));
-
- assert_eq!(
- subject
- .execute("foo".into(), Arc::new(CommandSource {}))
- .unwrap(),
- 42
- );
-}
-
-#[test]
fn create_and_execute_offset_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42));
assert_eq!(
subject
- .execute(input_with_offset("/foo", 1), Arc::new(CommandSource {}))
+ .execute(input_with_offset("/foo", 1), &CommandSource {})
.unwrap(),
42
);
@@ -50,18 +37,8 @@ fn create_and_merge_commands() {
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(), Arc::new(CommandSource {}))
- .unwrap(),
- 42
- );
- assert_eq!(
- subject
- .execute("base bar".into(), Arc::new(CommandSource {}))
- .unwrap(),
- 42
- );
+ assert_eq!(subject.execute("base foo", &CommandSource {}).unwrap(), 42);
+ assert_eq!(subject.execute("base bar", &CommandSource {}).unwrap(), 42);
}
#[test]
@@ -70,7 +47,7 @@ fn execute_unknown_command() {
subject.register(literal("bar"));
subject.register(literal("baz"));
- let execute_result = subject.execute("foo".into(), Arc::new(CommandSource {}));
+ let execute_result = subject.execute("foo", &CommandSource {});
let err = execute_result.err().unwrap();
match err.type_ {
@@ -85,7 +62,7 @@ fn execute_impermissible_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").requires(|_| false));
- let execute_result = subject.execute("foo".into(), Arc::new(CommandSource {}));
+ let execute_result = subject.execute("foo", &CommandSource {});
let err = execute_result.err().unwrap();
match err.type_ {
@@ -100,7 +77,7 @@ fn execute_empty_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal(""));
- let execute_result = subject.execute("".into(), Arc::new(CommandSource {}));
+ let execute_result = subject.execute("", &CommandSource {});
let err = execute_result.err().unwrap();
match err.type_ {
@@ -115,7 +92,7 @@ fn execute_unknown_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42));
- let execute_result = subject.execute("foo bar".into(), Arc::new(CommandSource {}));
+ let execute_result = subject.execute("foo bar", &CommandSource {});
let err = execute_result.err().unwrap();
match err.type_ {
@@ -130,7 +107,7 @@ fn execute_incorrect_literal() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42).then(literal("bar")));
- let execute_result = subject.execute("foo baz".into(), Arc::new(CommandSource {}));
+ let execute_result = subject.execute("foo baz", &CommandSource {});
let err = execute_result.err().unwrap();
match err.type_ {
@@ -150,7 +127,7 @@ fn execute_ambiguous_incorrect_argument() {
.then(literal("baz")),
);
- let execute_result = subject.execute("foo unknown".into(), Arc::new(CommandSource {}));
+ let execute_result = subject.execute("foo unknown", &CommandSource {});
let err = execute_result.err().unwrap();
match err.type_ {
@@ -172,12 +149,7 @@ fn execute_subcommand() {
.executes(|_| 42),
);
- assert_eq!(
- subject
- .execute("foo =".into(), Arc::new(CommandSource {}))
- .unwrap(),
- 100
- );
+ assert_eq!(subject.execute("foo =", &CommandSource {}).unwrap(), 100);
}
#[test]
@@ -185,7 +157,7 @@ fn parse_incomplete_literal() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").then(literal("bar").executes(|_| 42)));
- let parse = subject.parse("foo ".into(), Arc::new(CommandSource {}));
+ let parse = subject.parse("foo ".into(), &CommandSource {});
assert_eq!(parse.reader.remaining(), " ");
assert_eq!(parse.context.nodes.len(), 1);
}
@@ -195,7 +167,7 @@ fn parse_incomplete_argument() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").then(argument("bar", integer()).executes(|_| 42)));
- let parse = subject.parse("foo ".into(), Arc::new(CommandSource {}));
+ let parse = subject.parse("foo ".into(), &CommandSource {});
assert_eq!(parse.reader.remaining(), " ");
assert_eq!(parse.context.nodes.len(), 1);
}
@@ -210,12 +182,7 @@ fn execute_ambiguious_parent_subcommand() {
.then(argument("right", integer()).then(argument("sub", integer()).executes(|_| 100))),
);
- assert_eq!(
- subject
- .execute("test 1 2".into(), Arc::new(CommandSource {}))
- .unwrap(),
- 100
- );
+ assert_eq!(subject.execute("test 1 2", &CommandSource {}).unwrap(), 100);
}
#[test]
@@ -231,9 +198,7 @@ fn execute_ambiguious_parent_subcommand_via_redirect() {
subject.register(literal("redirect").redirect(real));
assert_eq!(
- subject
- .execute("redirect 1 2".into(), Arc::new(CommandSource {}))
- .unwrap(),
+ subject.execute("redirect 1 2", &CommandSource {}).unwrap(),
100
);
}
@@ -248,7 +213,7 @@ fn execute_redirected_multiple_times() {
let input = "redirected redirected actual";
- let parse = subject.parse(input.into(), Arc::new(CommandSource {}));
+ let parse = subject.parse(input.into(), &CommandSource {});
assert_eq!(parse.context.range.get(input), "redirected");
assert_eq!(parse.context.nodes.len(), 1);
assert_eq!(*parse.context.root.read(), *root.read());
@@ -299,7 +264,7 @@ fn execute_redirected() {
subject.register(literal("redirected").fork(subject.root.clone(), Arc::new(modifier)));
let input = "redirected actual";
- let parse = subject.parse(input.into(), Arc::new(CommandSource {}));
+ let parse = subject.parse(input.into(), CommandSource {});
assert_eq!(parse.context.range.get(input), "redirected");
assert_eq!(parse.context.nodes.len(), 1);
assert_eq!(*parse.context.root.read(), *subject.root.read());
@@ -314,7 +279,7 @@ fn execute_redirected() {
assert_eq!(*parse.context.root.read(), *subject.root.read());
assert_eq!(parent.nodes[0].range, parent.range);
assert_eq!(*parent.nodes[0].node.read(), *concrete_node.read());
- assert_eq!(parent.source, Arc::new(CommandSource {}));
+ assert_eq!(*parent.source, CommandSource {});
assert_eq!(CommandDispatcher::execute_parsed(parse).unwrap(), 2);
}
@@ -329,7 +294,7 @@ fn execute_orphaned_subcommand() {
.executes(|_| 42),
);
- let result = subject.execute("foo 5".into(), Arc::new(CommandSource {}));
+ let result = subject.execute("foo 5", &CommandSource {});
assert!(result.is_err());
let result = result.unwrap_err();
assert_eq!(
@@ -346,12 +311,7 @@ fn execute_invalid_other() {
subject.register(literal("w").executes(|_| panic!("This should not run")));
subject.register(literal("world").executes(|_| 42));
- assert_eq!(
- subject
- .execute("world".into(), Arc::new(CommandSource {}))
- .unwrap(),
- 42
- );
+ assert_eq!(subject.execute("world", &CommandSource {}).unwrap(), 42);
}
#[test]
@@ -364,7 +324,7 @@ fn parse_no_space_separator() {
.executes(|_| 42),
);
- let result = subject.execute("foo$".into(), Arc::new(CommandSource {}));
+ let result = subject.execute("foo$", &CommandSource {});
assert!(result.is_err());
let result = result.unwrap_err();
assert_eq!(
@@ -384,7 +344,7 @@ fn execute_invalid_subcommand() {
.executes(|_| 42),
);
- let result = subject.execute("foo bar".into(), Arc::new(CommandSource {}));
+ let result = subject.execute("foo bar", &CommandSource {});
assert!(result.is_err());
let result = result.unwrap_err();
// this fails for some reason, i blame mojang