diff options
| author | mat <github@matdoes.dev> | 2022-04-18 17:59:21 +0000 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-04-18 17:59:21 +0000 |
| commit | 17d9f676ccdc69743e7717bb91f7ff2999c065f8 (patch) | |
| tree | cf90d6664ee3c30fe1c2df8a9ecf9862a140200d /azalea-brigadier/src | |
| parent | e2c6131ac9eb3583b05a279c2347d4e3aebe084e (diff) | |
| download | azalea-drasl-17d9f676ccdc69743e7717bb91f7ff2999c065f8.tar.xz | |
general cleanup
Diffstat (limited to 'azalea-brigadier/src')
| -rw-r--r-- | azalea-brigadier/src/dispatcher.rs | 2 | ||||
| -rw-r--r-- | azalea-brigadier/src/lib.rs | 19 | ||||
| -rw-r--r-- | azalea-brigadier/src/string_reader.rs | 2 | ||||
| -rw-r--r-- | azalea-brigadier/src/tree.rs | 279 |
4 files changed, 15 insertions, 287 deletions
diff --git a/azalea-brigadier/src/dispatcher.rs b/azalea-brigadier/src/dispatcher.rs index 9f8edce4..ce89b81d 100644 --- a/azalea-brigadier/src/dispatcher.rs +++ b/azalea-brigadier/src/dispatcher.rs @@ -589,7 +589,7 @@ mod tests { let source1 = Rc::new(CommandSource {}); let source2 = Rc::new(CommandSource {}); - let modifier = move |source: &CommandContext<CommandSource>| -> Result<Vec<Rc<CommandSource>>, CommandSyntaxException> { + let modifier = move |_: &CommandContext<CommandSource>| -> Result<Vec<Rc<CommandSource>>, CommandSyntaxException> { Ok(vec![source1.clone(), source2.clone()]) }; diff --git a/azalea-brigadier/src/lib.rs b/azalea-brigadier/src/lib.rs index d3db8dcf..e359e274 100644 --- a/azalea-brigadier/src/lib.rs +++ b/azalea-brigadier/src/lib.rs @@ -17,6 +17,7 @@ mod tests { use crate::{ builder::{literal_argument_builder::literal, required_argument_builder::argument}, + context::CommandContext, dispatcher::CommandDispatcher, parsers::{get_integer, integer}, }; @@ -27,7 +28,7 @@ mod tests { #[test] fn it_works() { - let mut dispatcher = CommandDispatcher::<CommandSourceStack>::new(); + let mut dispatcher = CommandDispatcher::new(); let source = Rc::new(CommandSourceStack { player: "player".to_string(), @@ -35,11 +36,17 @@ mod tests { dispatcher.register( literal("foo") - .then(argument("bar", integer()).executes(|c| { - println!("Bar is {:?}", get_integer(c, "bar")); - 2 - })) - .executes(|c| { + .then(argument("bar", integer()).executes( + |c: &CommandContext<CommandSourceStack>| { + println!( + "Bar is {:?} and player is {}", + get_integer(c, "bar"), + c.source.player + ); + 2 + }, + )) + .executes(|_| { println!("Called foo with no arguments"); 1 }), diff --git a/azalea-brigadier/src/string_reader.rs b/azalea-brigadier/src/string_reader.rs index 5825871f..f220267a 100644 --- a/azalea-brigadier/src/string_reader.rs +++ b/azalea-brigadier/src/string_reader.rs @@ -824,7 +824,7 @@ mod test { #[test] fn expect_correct() { let mut reader = StringReader::from("abc".to_string()); - reader.expect('a'); + reader.expect('a').unwrap(); assert_eq!(reader.cursor(), 1); } diff --git a/azalea-brigadier/src/tree.rs b/azalea-brigadier/src/tree.rs deleted file mode 100644 index 5ca199fa..00000000 --- a/azalea-brigadier/src/tree.rs +++ /dev/null @@ -1,279 +0,0 @@ -use crate::{ - builder::{ - argument_builder::ArgumentBuilderType, literal_argument_builder::Literal, - required_argument_builder::Argument, - }, - context::{CommandContext, CommandContextBuilder, ParsedArgument}, - exceptions::{ - builtin_exceptions::BuiltInExceptions, command_syntax_exception::CommandSyntaxException, - }, - modifier::RedirectModifier, - string_range::StringRange, - string_reader::StringReader, -}; -use std::{cell::RefCell, collections::BTreeMap, fmt::Debug, hash::Hash, ptr, rc::Rc}; - -/// An ArgumentBuilder that has been built. -#[non_exhaustive] -pub struct CommandNode<S> { - pub value: ArgumentBuilderType, - - // we use BTreeMap instead of HashMap because it can be hashed - pub children: BTreeMap<String, Rc<RefCell<CommandNode<S>>>>, - pub literals: BTreeMap<String, Rc<RefCell<CommandNode<S>>>>, - pub arguments: BTreeMap<String, Rc<RefCell<CommandNode<S>>>>, - - pub command: Option<Rc<dyn Fn(&CommandContext<S>) -> i32>>, - pub requirement: Rc<dyn Fn(Rc<S>) -> bool>, - pub redirect: Option<Rc<RefCell<CommandNode<S>>>>, - pub forks: bool, - pub modifier: Option<Rc<RedirectModifier<S>>>, -} - -impl<S> Clone for CommandNode<S> { - fn clone(&self) -> Self { - Self { - value: self.value.clone(), - children: self.children.clone(), - literals: self.literals.clone(), - arguments: self.arguments.clone(), - command: self.command.clone(), - requirement: self.requirement.clone(), - redirect: self.redirect.clone(), - forks: self.forks, - modifier: self.modifier.clone(), - } - } -} - -#[derive(Debug)] -pub struct ParsedCommandNode<S> { - pub node: Rc<RefCell<CommandNode<S>>>, - pub range: StringRange, -} - -impl<S> Clone for ParsedCommandNode<S> { - fn clone(&self) -> Self { - Self { - node: self.node.clone(), - range: self.range.clone(), - } - } -} - -impl<S> CommandNode<S> { - /// Gets the literal, or panics. You should use match if you're not certain about the type. - pub fn literal(&self) -> &Literal { - match self.value { - ArgumentBuilderType::Literal(ref literal) => literal, - _ => panic!("CommandNode::literal() called on non-literal node"), - } - } - /// Gets the argument, or panics. You should use match if you're not certain about the type. - pub fn argument(&self) -> &Argument { - match self.value { - ArgumentBuilderType::Argument(ref argument) => argument, - _ => panic!("CommandNode::argument() called on non-argument node"), - } - } - - pub fn get_relevant_nodes(&self, input: &mut StringReader) -> Vec<Rc<RefCell<CommandNode<S>>>> { - let literals = &self.literals; - - if !literals.is_empty() { - let cursor = input.cursor(); - while input.can_read() && input.peek() != ' ' { - input.skip(); - } - let text: String = input - .string() - .chars() - .skip(cursor) - .take(input.cursor() - cursor) - .collect(); - input.cursor = cursor; - let literal = literals.get(&text); - if let Some(literal) = literal { - return vec![literal.clone()]; - } else { - return self.arguments.values().cloned().collect(); - } - } else { - self.arguments.values().cloned().collect() - } - } - - pub fn can_use(&self, source: Rc<S>) -> bool { - (self.requirement)(source) - } - - pub fn add_child(&mut self, node: &Rc<RefCell<CommandNode<S>>>) { - let child = self.children.get(node.borrow().name()); - if let Some(child) = child { - // We've found something to merge onto - if let Some(command) = &node.borrow().command { - child.borrow_mut().command = Some(command.clone()); - } - for grandchild in node.borrow().children.values() { - child.borrow_mut().add_child(grandchild); - } - } else { - self.children - .insert(node.borrow().name().to_string(), node.clone()); - match &node.borrow().value { - ArgumentBuilderType::Literal(literal) => { - self.literals.insert(literal.value.clone(), node.clone()); - } - ArgumentBuilderType::Argument(argument) => { - self.arguments.insert(argument.name.clone(), node.clone()); - } - } - } - } - - pub fn name(&self) -> &str { - match &self.value { - ArgumentBuilderType::Argument(argument) => &argument.name, - ArgumentBuilderType::Literal(literal) => &literal.value, - } - } - - pub fn child(&self, name: &str) -> Option<Rc<RefCell<CommandNode<S>>>> { - self.children.get(name).cloned() - } - - pub fn parse_with_context( - &self, - reader: &mut StringReader, - context_builder: &mut CommandContextBuilder<S>, - ) -> Result<(), CommandSyntaxException> { - match self.value { - ArgumentBuilderType::Argument(ref argument) => { - let start = reader.cursor(); - // TODO: handle this better - let result = argument.parse(reader)?; - let parsed = ParsedArgument { - range: StringRange::between(start, reader.cursor()), - result, - }; - - context_builder.with_argument(&argument.name, parsed.clone()); - context_builder.with_node(Rc::new(RefCell::new(self.clone())), parsed.range); - - Ok(()) - } - ArgumentBuilderType::Literal(ref literal) => { - let start = reader.cursor(); - let end = self.parse(reader); - - if let Some(end) = end { - context_builder.with_node( - Rc::new(RefCell::new(self.clone())), - StringRange::between(start, end), - ); - return Ok(()); - } - - Err(BuiltInExceptions::LiteralIncorrect { - expected: literal.value.clone(), - } - .create_with_context(reader)) - } - } - } - - fn parse(&self, reader: &mut StringReader) -> Option<usize> { - match self.value { - ArgumentBuilderType::Argument(_) => { - panic!("Can't parse argument.") - } - ArgumentBuilderType::Literal(ref literal) => { - let start = reader.cursor(); - if reader.can_read_length(literal.value.len()) { - let end = start + literal.value.len(); - if reader - .string() - .get(start..end) - .expect("Couldn't slice reader correctly?") - == literal.value - { - reader.cursor = end; - if !reader.can_read() || reader.peek() == ' ' { - return Some(end); - } else { - reader.cursor = start; - } - } - } - } - } - None - } -} - -impl<S> Debug for CommandNode<S> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("CommandNode") - .field("value", &self.value) - .field("children", &self.children) - .field("command", &self.command.is_some()) - // .field("requirement", &self.requirement) - .field("redirect", &self.redirect) - .field("forks", &self.forks) - // .field("modifier", &self.modifier) - .finish() - } -} - -impl<S> Default for CommandNode<S> { - fn default() -> Self { - Self { - value: ArgumentBuilderType::Literal(Literal::default()), - - children: BTreeMap::new(), - literals: BTreeMap::new(), - arguments: BTreeMap::new(), - - command: None, - requirement: Rc::new(|_| true), - redirect: None, - forks: false, - modifier: None, - } - } -} - -impl<S> Hash for CommandNode<S> { - fn hash<H: std::hash::Hasher>(&self, state: &mut H) { - // hash the children - for (k, v) in &self.children { - k.hash(state); - v.borrow().hash(state); - } - // i hope this works because if doesn't then that'll be a problem - ptr::hash(&self.command, state); - } -} - -impl<S> PartialEq for CommandNode<S> { - fn eq(&self, other: &Self) -> bool { - if self.children != other.children { - 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; - } - } else { - return false; - } - } else if other.command.is_some() { - return false; - } - true - } -} -impl<S> Eq for CommandNode<S> {} |
