azalea_brigadier/context/
command_context.rs1use std::{
2 any::Any,
3 collections::HashMap,
4 fmt::{self, Debug},
5 rc::Rc,
6 sync::Arc,
7};
8
9use parking_lot::RwLock;
10
11use super::{ParsedArgument, parsed_command_node::ParsedCommandNode, string_range::StringRange};
12use crate::{
13 modifier::RedirectModifier,
14 tree::{Command, CommandNode},
15};
16
17pub struct CommandContext<S> {
19 pub source: Arc<S>,
20 pub(super) input: String,
21 pub(super) arguments: HashMap<String, ParsedArgument>,
22 pub(super) command: Command<S>,
23 pub(super) root_node: Arc<RwLock<CommandNode<S>>>,
24 pub(super) nodes: Vec<ParsedCommandNode<S>>,
25 pub(super) range: StringRange,
26 pub(super) child: Option<Rc<CommandContext<S>>>,
27 pub(super) modifier: Option<Arc<RedirectModifier<S>>>,
28 pub(super) forks: bool,
29}
30
31impl<S> Clone for CommandContext<S> {
32 fn clone(&self) -> Self {
33 Self {
34 source: self.source.clone(),
35 input: self.input.clone(),
36 arguments: self.arguments.clone(),
37 command: self.command.clone(),
38 root_node: self.root_node.clone(),
39 nodes: self.nodes.clone(),
40 range: self.range,
41 child: self.child.clone(),
42 modifier: self.modifier.clone(),
43 forks: self.forks,
44 }
45 }
46}
47
48impl<S> Debug for CommandContext<S> {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 f.debug_struct("CommandContext")
51 .field("input", &self.input)
53 .field("range", &self.range)
58 .field("child", &self.child)
59 .field("forks", &self.forks)
61 .finish()
62 }
63}
64
65impl<S> CommandContext<S> {
66 pub fn copy_for(&self, source: Arc<S>) -> Self {
67 if Arc::ptr_eq(&source, &self.source) {
68 return self.clone();
70 }
71
72 CommandContext {
73 source,
74 input: self.input.clone(),
75 arguments: self.arguments.clone(),
76 command: self.command.clone(),
77 root_node: self.root_node.clone(),
78 nodes: self.nodes.clone(),
79 range: self.range,
80 child: self.child.clone(),
81 modifier: self.modifier.clone(),
82 forks: self.forks,
83 }
84 }
85
86 pub fn child(&self) -> Option<&CommandContext<S>> {
87 self.child.as_ref().map(|c| c.as_ref())
88 }
89
90 pub fn last_child(&self) -> &CommandContext<S> {
91 let mut result = self;
92 while let Some(child) = result.child() {
93 result = child;
94 }
95 result
96 }
97
98 pub fn command(&self) -> &Command<S> {
99 &self.command
100 }
101
102 pub fn argument(&self, name: &str) -> Option<&dyn Any> {
103 let argument = self.arguments.get(name);
104 argument.map(|a| a.result.as_ref())
105 }
106
107 pub fn redirect_modifier(&self) -> Option<&RedirectModifier<S>> {
108 self.modifier.as_ref().map(|m| m.as_ref())
109 }
110
111 pub fn range(&self) -> &StringRange {
112 &self.range
113 }
114
115 pub fn input(&self) -> &str {
116 &self.input
117 }
118
119 pub fn root_node(&self) -> &Arc<RwLock<CommandNode<S>>> {
120 &self.root_node
121 }
122
123 pub fn nodes(&self) -> &[ParsedCommandNode<S>] {
124 &self.nodes
125 }
126
127 pub fn has_nodes(&self) -> bool {
128 !self.nodes.is_empty()
129 }
130
131 pub fn is_forked(&self) -> bool {
132 self.forks
133 }
134}