diff options
| author | mat <github@matdoes.dev> | 2022-04-17 14:02:13 -0500 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-04-17 14:02:13 -0500 |
| commit | a72a47ced76065caf739898954cd18edbc39174b (patch) | |
| tree | 5526c7663f253bbd7c8318b9d98413f1f2074852 /azalea-brigadier/src/context.rs | |
| parent | 4ff67d4917ce333232189e86aee09f2d82451fc6 (diff) | |
| download | azalea-drasl-a72a47ced76065caf739898954cd18edbc39174b.tar.xz | |
Rewrite brigadier
Diffstat (limited to 'azalea-brigadier/src/context.rs')
| -rw-r--r-- | azalea-brigadier/src/context.rs | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/azalea-brigadier/src/context.rs b/azalea-brigadier/src/context.rs new file mode 100644 index 00000000..6d4dec88 --- /dev/null +++ b/azalea-brigadier/src/context.rs @@ -0,0 +1,145 @@ +use std::{any::Any, cell::RefCell, collections::HashMap, fmt::Debug, ptr, rc::Rc}; + +use crate::{ + dispatcher::CommandDispatcher, modifier::RedirectModifier, string_range::StringRange, + tree::CommandNode, +}; + +#[derive(Clone)] +pub struct CommandContextBuilder<S: Any + Clone> { + pub arguments: HashMap<String, ParsedArgument>, + pub root: Rc<RefCell<CommandNode<S>>>, + pub nodes: Vec<Rc<CommandNode<S>>>, + pub dispatcher: Rc<CommandDispatcher<S>>, + pub source: Rc<S>, + pub command: Option<Rc<dyn Fn(&CommandContext<S>) -> i32>>, + pub child: Option<Rc<CommandContextBuilder<S>>>, + pub range: StringRange, + pub modifier: Option<Rc<dyn RedirectModifier<S>>>, + pub forks: bool, +} + +impl<S: Any + Clone> CommandContextBuilder<S> { + // CommandDispatcher<S> dispatcher, final S source, final CommandNode<S> rootNode, final int start + pub fn new( + dispatcher: Rc<CommandDispatcher<S>>, + source: Rc<S>, + root_node: Rc<RefCell<CommandNode<S>>>, + start: usize, + ) -> Self { + Self { + arguments: HashMap::new(), + root: root_node, + source, + range: StringRange::at(start), + command: None, + dispatcher, + nodes: vec![], + // rootNode, + // start, + child: None, + modifier: None, + forks: false, + } + } + + pub fn with_command( + &mut self, + command: &Option<Rc<dyn Fn(&CommandContext<S>) -> i32>>, + ) -> &Self { + self.command = command.clone(); + self + } + pub fn with_child(&mut self, child: Rc<CommandContextBuilder<S>>) -> &Self { + self.child = Some(child); + self + } + pub fn with_argument(&mut self, name: &str, argument: ParsedArgument) -> &Self { + self.arguments.insert(name.to_string(), argument); + self + } + pub fn with_node(&mut self, node: Rc<CommandNode<S>>, range: StringRange) -> &Self { + self.nodes.push(node.clone()); + self.range = StringRange::encompassing(&self.range, &range); + self.modifier = node.modifier.clone(); + self.forks = node.forks; + self + } + + pub fn build(&self, input: &str) -> CommandContext<S> { + CommandContext { + arguments: self.arguments.clone(), + root_node: self.root.clone(), + nodes: self.nodes.clone(), + source: self.source.clone(), + command: self.command.clone(), + child: self.child.clone().map(|c| Rc::new(c.build(&input))), + range: self.range.clone(), + forks: self.forks, + modifier: self.modifier.clone(), + input: input.to_string(), + } + } +} + +impl<S: Any + Clone> Debug for CommandContextBuilder<S> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("CommandContextBuilder") + // .field("arguments", &self.arguments) + .field("root", &self.root) + .field("nodes", &self.nodes) + // .field("dispatcher", &self.dispatcher) + // .field("source", &self.source) + // .field("command", &self.command) + .field("child", &self.child) + .field("range", &self.range) + // .field("modifier", &self.modifier) + .field("forks", &self.forks) + .finish() + } +} + +#[derive(Clone)] +pub struct ParsedArgument { + pub range: StringRange, + pub result: Rc<dyn Any>, +} + +#[derive(Clone)] +/// A built `CommandContextBuilder`. +pub struct CommandContext<S: Any + Clone> { + pub source: Rc<S>, + pub input: String, + pub arguments: HashMap<String, ParsedArgument>, + pub command: Option<Rc<dyn Fn(&CommandContext<S>) -> i32>>, + pub root_node: Rc<RefCell<CommandNode<S>>>, + pub nodes: Vec<Rc<CommandNode<S>>>, + pub range: StringRange, + pub child: Option<Rc<CommandContext<S>>>, + pub modifier: Option<Rc<dyn RedirectModifier<S>>>, + pub forks: bool, +} + +impl<S: Any + Clone> CommandContext<S> { + pub fn copy_for(&self, source: Rc<S>) -> Self { + if Rc::ptr_eq(&source, &self.source) { + return self.clone(); + } + return CommandContext { + source, + input: self.input.clone(), + arguments: self.arguments.clone(), + command: self.command.clone(), + root_node: self.root_node.clone(), + nodes: self.nodes.clone(), + range: self.range.clone(), + child: self.child.clone(), + modifier: self.modifier.clone(), + forks: self.forks, + }; + } + + pub fn has_nodes(&self) -> bool { + return !self.nodes.is_empty(); + } +} |
