aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2023-05-05 23:23:11 -0500
committermat <git@matdoes.dev>2023-05-05 23:23:11 -0500
commitf825544e2776ab545ff0a9c674b68183120695cb (patch)
treea294fa38650e4ce511fc4d6c8b166f13e23ba18e
parent12370ab07609bf78baef4ec2302fa4ba44317dae (diff)
downloadazalea-drasl-f825544e2776ab545ff0a9c674b68183120695cb.tar.xz
CommandDispatcher is now Send+Sync
-rwxr-xr-xazalea-brigadier/src/builder/argument_builder.rs20
-rwxr-xr-xazalea-brigadier/src/builder/required_argument_builder.rs13
-rwxr-xr-xazalea-brigadier/src/command_dispatcher.rs10
-rwxr-xr-xazalea-brigadier/src/context/command_context.rs10
-rwxr-xr-xazalea-brigadier/src/context/command_context_builder.rs14
-rwxr-xr-xazalea-brigadier/src/modifier.rs4
-rwxr-xr-xazalea-brigadier/src/tree/mod.rs14
-rwxr-xr-xazalea-brigadier/tests/command_dispatcher_test.rs54
8 files changed, 71 insertions, 68 deletions
diff --git a/azalea-brigadier/src/builder/argument_builder.rs b/azalea-brigadier/src/builder/argument_builder.rs
index a1f3d6ae..c6f2146a 100755
--- a/azalea-brigadier/src/builder/argument_builder.rs
+++ b/azalea-brigadier/src/builder/argument_builder.rs
@@ -7,7 +7,7 @@ use crate::{
};
use super::{literal_argument_builder::Literal, required_argument_builder::Argument};
-use std::{fmt::Debug, rc::Rc, sync::Arc};
+use std::{fmt::Debug, sync::Arc};
#[derive(Debug, Clone)]
pub enum ArgumentBuilderType {
@@ -20,11 +20,11 @@ pub struct ArgumentBuilder<S> {
arguments: CommandNode<S>,
command: Command<S>,
- requirement: Rc<dyn Fn(Rc<S>) -> bool>,
+ requirement: Arc<dyn Fn(Arc<S>) -> bool + Send + Sync>,
target: Option<Arc<RwLock<CommandNode<S>>>>,
forks: bool,
- modifier: Option<Rc<RedirectModifier<S>>>,
+ modifier: Option<Arc<RedirectModifier<S>>>,
}
/// A node that isn't yet built.
@@ -36,7 +36,7 @@ impl<S> ArgumentBuilder<S> {
..Default::default()
},
command: None,
- requirement: Rc::new(|_| true),
+ requirement: Arc::new(|_| true),
forks: false,
modifier: None,
target: None,
@@ -54,17 +54,17 @@ impl<S> ArgumentBuilder<S> {
pub fn executes<F>(mut self, f: F) -> Self
where
- F: Fn(&CommandContext<S>) -> i32 + 'static,
+ F: Fn(&CommandContext<S>) -> i32 + Send + Sync + 'static,
{
- self.command = Some(Rc::new(f));
+ self.command = Some(Arc::new(f));
self
}
pub fn requires<F>(mut self, requirement: F) -> Self
where
- F: Fn(Rc<S>) -> bool + 'static,
+ F: Fn(Arc<S>) -> bool + Send + Sync + 'static,
{
- self.requirement = Rc::new(requirement);
+ self.requirement = Arc::new(requirement);
self
}
@@ -75,7 +75,7 @@ impl<S> ArgumentBuilder<S> {
pub fn fork(
self,
target: Arc<RwLock<CommandNode<S>>>,
- modifier: Rc<RedirectModifier<S>>,
+ modifier: Arc<RedirectModifier<S>>,
) -> Self {
self.forward(target, Some(modifier), true)
}
@@ -83,7 +83,7 @@ impl<S> ArgumentBuilder<S> {
pub fn forward(
mut self,
target: Arc<RwLock<CommandNode<S>>>,
- modifier: Option<Rc<RedirectModifier<S>>>,
+ modifier: Option<Arc<RedirectModifier<S>>>,
fork: bool,
) -> Self {
if !self.arguments.children.is_empty() {
diff --git a/azalea-brigadier/src/builder/required_argument_builder.rs b/azalea-brigadier/src/builder/required_argument_builder.rs
index 9d4d9e0a..0363d204 100755
--- a/azalea-brigadier/src/builder/required_argument_builder.rs
+++ b/azalea-brigadier/src/builder/required_argument_builder.rs
@@ -2,17 +2,17 @@ use super::argument_builder::{ArgumentBuilder, ArgumentBuilderType};
use crate::{
arguments::ArgumentType, exceptions::CommandSyntaxException, string_reader::StringReader,
};
-use std::{any::Any, fmt::Debug, rc::Rc};
+use std::{any::Any, fmt::Debug, rc::Rc, sync::Arc};
/// An argument node type. The `T` type parameter is the type of the argument,
/// which can be anything.
#[derive(Clone)]
pub struct Argument {
pub name: String,
- parser: Rc<dyn ArgumentType>,
+ parser: Arc<dyn ArgumentType + Send + Sync>,
}
impl Argument {
- pub fn new(name: &str, parser: Rc<dyn ArgumentType>) -> Self {
+ pub fn new(name: &str, parser: Arc<dyn ArgumentType + Send + Sync>) -> Self {
Self {
name: name.to_string(),
parser,
@@ -40,6 +40,9 @@ impl Debug for Argument {
}
/// Shortcut for creating a new argument builder node.
-pub fn argument<S>(name: &str, parser: impl ArgumentType + 'static) -> ArgumentBuilder<S> {
- ArgumentBuilder::new(Argument::new(name, Rc::new(parser)).into())
+pub fn argument<S>(
+ name: &str,
+ parser: impl ArgumentType + Send + Sync + 'static,
+) -> ArgumentBuilder<S> {
+ ArgumentBuilder::new(Argument::new(name, Arc::new(parser)).into())
}
diff --git a/azalea-brigadier/src/command_dispatcher.rs b/azalea-brigadier/src/command_dispatcher.rs
index 0d84171e..384a28dd 100755
--- a/azalea-brigadier/src/command_dispatcher.rs
+++ b/azalea-brigadier/src/command_dispatcher.rs
@@ -13,8 +13,8 @@ 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.
#[derive(Default)]
pub struct CommandDispatcher<S>
-// where
-// Self: Sync + Send,
+where
+ Self: Sync + Send,
{
pub root: Arc<RwLock<CommandNode<S>>>,
}
@@ -32,7 +32,7 @@ impl<S> CommandDispatcher<S> {
build
}
- pub fn parse(&self, command: StringReader, source: Rc<S>) -> ParseResults<S> {
+ pub fn parse(&self, command: StringReader, source: Arc<S>) -> ParseResults<S> {
let context = CommandContextBuilder::new(self, source, self.root.clone(), command.cursor());
self.parse_nodes(&self.root, &command, context).unwrap()
}
@@ -91,7 +91,7 @@ impl<S> CommandDispatcher<S> {
let parse = self
.parse_nodes(redirect, &reader, child_context)
.expect("Parsing nodes failed");
- context.with_child(Rc::new(parse.context));
+ context.with_child(Arc::new(parse.context));
return Ok(ParseResults {
context,
reader: parse.reader,
@@ -144,7 +144,7 @@ impl<S> CommandDispatcher<S> {
pub fn execute(
&self,
input: StringReader,
- source: Rc<S>,
+ source: Arc<S>,
) -> Result<i32, CommandSyntaxException> {
let parse = self.parse(input, source);
Self::execute_parsed(parse)
diff --git a/azalea-brigadier/src/context/command_context.rs b/azalea-brigadier/src/context/command_context.rs
index 88af2002..1734bb05 100755
--- a/azalea-brigadier/src/context/command_context.rs
+++ b/azalea-brigadier/src/context/command_context.rs
@@ -9,15 +9,15 @@ use std::{any::Any, collections::HashMap, fmt::Debug, rc::Rc, sync::Arc};
/// A built `CommandContextBuilder`.
pub struct CommandContext<S> {
- pub source: Rc<S>,
+ pub source: Arc<S>,
pub input: String,
pub arguments: HashMap<String, ParsedArgument>,
pub command: Command<S>,
pub root_node: Arc<RwLock<CommandNode<S>>>,
pub nodes: Vec<ParsedCommandNode<S>>,
pub range: StringRange,
- pub child: Option<Rc<CommandContext<S>>>,
- pub modifier: Option<Rc<RedirectModifier<S>>>,
+ pub child: Option<Arc<CommandContext<S>>>,
+ pub modifier: Option<Arc<RedirectModifier<S>>>,
pub forks: bool,
}
@@ -56,8 +56,8 @@ impl<S> Debug for CommandContext<S> {
}
impl<S> CommandContext<S> {
- pub fn copy_for(&self, source: Rc<S>) -> Self {
- if Rc::ptr_eq(&source, &self.source) {
+ pub fn copy_for(&self, source: Arc<S>) -> Self {
+ if Arc::ptr_eq(&source, &self.source) {
return self.clone();
}
CommandContext {
diff --git a/azalea-brigadier/src/context/command_context_builder.rs b/azalea-brigadier/src/context/command_context_builder.rs
index 54063879..78088941 100755
--- a/azalea-brigadier/src/context/command_context_builder.rs
+++ b/azalea-brigadier/src/context/command_context_builder.rs
@@ -9,18 +9,18 @@ use crate::{
modifier::RedirectModifier,
tree::{Command, CommandNode},
};
-use std::{collections::HashMap, fmt::Debug, rc::Rc, sync::Arc};
+use std::{collections::HashMap, fmt::Debug, sync::Arc};
pub struct CommandContextBuilder<'a, S> {
pub arguments: HashMap<String, ParsedArgument>,
pub root: Arc<RwLock<CommandNode<S>>>,
pub nodes: Vec<ParsedCommandNode<S>>,
pub dispatcher: &'a CommandDispatcher<S>,
- pub source: Rc<S>,
+ pub source: Arc<S>,
pub command: Command<S>,
- pub child: Option<Rc<CommandContextBuilder<'a, S>>>,
+ pub child: Option<Arc<CommandContextBuilder<'a, S>>>,
pub range: StringRange,
- pub modifier: Option<Rc<RedirectModifier<S>>>,
+ pub modifier: Option<Arc<RedirectModifier<S>>>,
pub forks: bool,
}
@@ -44,7 +44,7 @@ impl<S> Clone for CommandContextBuilder<'_, S> {
impl<'a, S> CommandContextBuilder<'a, S> {
pub fn new(
dispatcher: &'a CommandDispatcher<S>,
- source: Rc<S>,
+ source: Arc<S>,
root_node: Arc<RwLock<CommandNode<S>>>,
start: usize,
) -> Self {
@@ -66,7 +66,7 @@ impl<'a, S> CommandContextBuilder<'a, S> {
self.command = command.clone();
self
}
- pub fn with_child(&mut self, child: Rc<CommandContextBuilder<'a, S>>) -> &Self {
+ pub fn with_child(&mut self, child: Arc<CommandContextBuilder<'a, S>>) -> &Self {
self.child = Some(child);
self
}
@@ -92,7 +92,7 @@ impl<'a, S> CommandContextBuilder<'a, 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| Arc::new(c.build(input))),
range: self.range.clone(),
forks: self.forks,
modifier: self.modifier.clone(),
diff --git a/azalea-brigadier/src/modifier.rs b/azalea-brigadier/src/modifier.rs
index d40d59f9..bebdd0cb 100755
--- a/azalea-brigadier/src/modifier.rs
+++ b/azalea-brigadier/src/modifier.rs
@@ -1,6 +1,6 @@
-use std::rc::Rc;
+use std::sync::Arc;
use crate::{context::CommandContext, exceptions::CommandSyntaxException};
pub type RedirectModifier<S> =
- dyn Fn(&CommandContext<S>) -> Result<Vec<Rc<S>>, CommandSyntaxException>;
+ dyn Fn(&CommandContext<S>) -> Result<Vec<Arc<S>>, CommandSyntaxException> + Send + Sync;
diff --git a/azalea-brigadier/src/tree/mod.rs b/azalea-brigadier/src/tree/mod.rs
index 902e288b..cec972dc 100755
--- a/azalea-brigadier/src/tree/mod.rs
+++ b/azalea-brigadier/src/tree/mod.rs
@@ -10,9 +10,9 @@ use crate::{
modifier::RedirectModifier,
string_reader::StringReader,
};
-use std::{collections::HashMap, fmt::Debug, hash::Hash, ptr, rc::Rc, sync::Arc};
+use std::{collections::HashMap, fmt::Debug, hash::Hash, ptr, sync::Arc};
-pub type Command<S> = Option<Rc<dyn Fn(&CommandContext<S>) -> i32>>;
+pub type Command<S> = Option<Arc<dyn Fn(&CommandContext<S>) -> i32 + Send + Sync>>;
/// An ArgumentBuilder that has been built.
#[non_exhaustive]
@@ -24,10 +24,10 @@ pub struct CommandNode<S> {
pub arguments: HashMap<String, Arc<RwLock<CommandNode<S>>>>,
pub command: Command<S>,
- pub requirement: Rc<dyn Fn(Rc<S>) -> bool>,
+ pub requirement: Arc<dyn Fn(Arc<S>) -> bool + Send + Sync>,
pub redirect: Option<Arc<RwLock<CommandNode<S>>>>,
pub forks: bool,
- pub modifier: Option<Rc<RedirectModifier<S>>>,
+ pub modifier: Option<Arc<RedirectModifier<S>>>,
}
impl<S> Clone for CommandNode<S> {
@@ -90,7 +90,7 @@ impl<S> CommandNode<S> {
}
}
- pub fn can_use(&self, source: Rc<S>) -> bool {
+ pub fn can_use(&self, source: Arc<S>) -> bool {
(self.requirement)(source)
}
@@ -221,7 +221,7 @@ impl<S> Default for CommandNode<S> {
arguments: HashMap::new(),
command: None,
- requirement: Rc::new(|_| true),
+ requirement: Arc::new(|_| true),
redirect: None,
forks: false,
modifier: None,
@@ -257,7 +257,7 @@ impl<S> PartialEq for CommandNode<S> {
// 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) {
+ if !Arc::ptr_eq(selfexecutes, otherexecutes) {
return false;
}
} else {
diff --git a/azalea-brigadier/tests/command_dispatcher_test.rs b/azalea-brigadier/tests/command_dispatcher_test.rs
index fb0085ba..4479cfa2 100755
--- a/azalea-brigadier/tests/command_dispatcher_test.rs
+++ b/azalea-brigadier/tests/command_dispatcher_test.rs
@@ -1,4 +1,4 @@
-use std::rc::Rc;
+use std::sync::Arc;
use azalea_brigadier::{
arguments::integer_argument_type::integer,
@@ -25,7 +25,7 @@ fn create_and_execute_command() {
assert_eq!(
subject
- .execute("foo".into(), Rc::new(CommandSource {}))
+ .execute("foo".into(), Arc::new(CommandSource {}))
.unwrap(),
42
);
@@ -38,7 +38,7 @@ fn create_and_execute_offset_command() {
assert_eq!(
subject
- .execute(input_with_offset("/foo", 1), Rc::new(CommandSource {}))
+ .execute(input_with_offset("/foo", 1), Arc::new(CommandSource {}))
.unwrap(),
42
);
@@ -52,13 +52,13 @@ fn create_and_merge_commands() {
assert_eq!(
subject
- .execute("base foo".into(), Rc::new(CommandSource {}))
+ .execute("base foo".into(), Arc::new(CommandSource {}))
.unwrap(),
42
);
assert_eq!(
subject
- .execute("base bar".into(), Rc::new(CommandSource {}))
+ .execute("base bar".into(), Arc::new(CommandSource {}))
.unwrap(),
42
);
@@ -70,7 +70,7 @@ fn execute_unknown_command() {
subject.register(literal("bar"));
subject.register(literal("baz"));
- let execute_result = subject.execute("foo".into(), Rc::new(CommandSource {}));
+ let execute_result = subject.execute("foo".into(), Arc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
@@ -85,7 +85,7 @@ fn execute_impermissible_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").requires(|_| false));
- let execute_result = subject.execute("foo".into(), Rc::new(CommandSource {}));
+ let execute_result = subject.execute("foo".into(), Arc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
@@ -100,7 +100,7 @@ fn execute_empty_command() {
let mut subject = CommandDispatcher::new();
subject.register(literal(""));
- let execute_result = subject.execute("".into(), Rc::new(CommandSource {}));
+ let execute_result = subject.execute("".into(), Arc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
@@ -115,7 +115,7 @@ fn execute_unknown_subcommand() {
let mut subject = CommandDispatcher::new();
subject.register(literal("foo").executes(|_| 42));
- let execute_result = subject.execute("foo bar".into(), Rc::new(CommandSource {}));
+ let execute_result = subject.execute("foo bar".into(), Arc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
@@ -130,7 +130,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(), Rc::new(CommandSource {}));
+ let execute_result = subject.execute("foo baz".into(), Arc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
@@ -150,7 +150,7 @@ fn execute_ambiguous_incorrect_argument() {
.then(literal("baz")),
);
- let execute_result = subject.execute("foo unknown".into(), Rc::new(CommandSource {}));
+ let execute_result = subject.execute("foo unknown".into(), Arc::new(CommandSource {}));
let err = execute_result.err().unwrap();
match err.type_ {
@@ -174,7 +174,7 @@ fn execute_subcommand() {
assert_eq!(
subject
- .execute("foo =".into(), Rc::new(CommandSource {}))
+ .execute("foo =".into(), Arc::new(CommandSource {}))
.unwrap(),
100
);
@@ -185,7 +185,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(), Rc::new(CommandSource {}));
+ let parse = subject.parse("foo ".into(), Arc::new(CommandSource {}));
assert_eq!(parse.reader.remaining(), " ");
assert_eq!(parse.context.nodes.len(), 1);
}
@@ -195,7 +195,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(), Rc::new(CommandSource {}));
+ let parse = subject.parse("foo ".into(), Arc::new(CommandSource {}));
assert_eq!(parse.reader.remaining(), " ");
assert_eq!(parse.context.nodes.len(), 1);
}
@@ -212,7 +212,7 @@ fn execute_ambiguious_parent_subcommand() {
assert_eq!(
subject
- .execute("test 1 2".into(), Rc::new(CommandSource {}))
+ .execute("test 1 2".into(), Arc::new(CommandSource {}))
.unwrap(),
100
);
@@ -232,7 +232,7 @@ fn execute_ambiguious_parent_subcommand_via_redirect() {
assert_eq!(
subject
- .execute("redirect 1 2".into(), Rc::new(CommandSource {}))
+ .execute("redirect 1 2".into(), Arc::new(CommandSource {}))
.unwrap(),
100
);
@@ -248,7 +248,7 @@ fn execute_redirected_multiple_times() {
let input = "redirected redirected actual";
- let parse = subject.parse(input.into(), Rc::new(CommandSource {}));
+ let parse = subject.parse(input.into(), Arc::new(CommandSource {}));
assert_eq!(parse.context.range.get(input), "redirected");
assert_eq!(parse.context.nodes.len(), 1);
assert_eq!(*parse.context.root.read(), *root.read());
@@ -287,19 +287,19 @@ fn execute_redirected_multiple_times() {
fn execute_redirected() {
let mut subject = CommandDispatcher::new();
- let source1 = Rc::new(CommandSource {});
- let source2 = Rc::new(CommandSource {});
+ let source1 = Arc::new(CommandSource {});
+ let source2 = Arc::new(CommandSource {});
- let modifier = move |_: &CommandContext<CommandSource>| -> Result<Vec<Rc<CommandSource>>, CommandSyntaxException> {
+ let modifier = move |_: &CommandContext<CommandSource>| -> Result<Vec<Arc<CommandSource>>, CommandSyntaxException> {
Ok(vec![source1.clone(), source2.clone()])
};
let concrete_node = subject.register(literal("actual").executes(|_| 42));
let redirect_node =
- subject.register(literal("redirected").fork(subject.root.clone(), Rc::new(modifier)));
+ subject.register(literal("redirected").fork(subject.root.clone(), Arc::new(modifier)));
let input = "redirected actual";
- let parse = subject.parse(input.into(), Rc::new(CommandSource {}));
+ let parse = subject.parse(input.into(), Arc::new(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 +314,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, Rc::new(CommandSource {}));
+ assert_eq!(parent.source, Arc::new(CommandSource {}));
assert_eq!(CommandDispatcher::execute_parsed(parse).unwrap(), 2);
}
@@ -329,7 +329,7 @@ fn execute_orphaned_subcommand() {
.executes(|_| 42),
);
- let result = subject.execute("foo 5".into(), Rc::new(CommandSource {}));
+ let result = subject.execute("foo 5".into(), Arc::new(CommandSource {}));
assert!(result.is_err());
let result = result.unwrap_err();
assert_eq!(
@@ -348,7 +348,7 @@ fn execute_invalid_other() {
assert_eq!(
subject
- .execute("world".into(), Rc::new(CommandSource {}))
+ .execute("world".into(), Arc::new(CommandSource {}))
.unwrap(),
42
);
@@ -364,7 +364,7 @@ fn parse_no_space_separator() {
.executes(|_| 42),
);
- let result = subject.execute("foo$".into(), Rc::new(CommandSource {}));
+ let result = subject.execute("foo$".into(), Arc::new(CommandSource {}));
assert!(result.is_err());
let result = result.unwrap_err();
assert_eq!(
@@ -384,7 +384,7 @@ fn execute_invalid_subcommand() {
.executes(|_| 42),
);
- let result = subject.execute("foo bar".into(), Rc::new(CommandSource {}));
+ let result = subject.execute("foo bar".into(), Arc::new(CommandSource {}));
assert!(result.is_err());
let result = result.unwrap_err();
// this fails for some reason, i blame mojang