azalea_brigadier/builder/
argument_builder.rs1use std::{
2 fmt::{self, Debug},
3 sync::Arc,
4};
5
6use parking_lot::RwLock;
7
8use super::{literal_argument_builder::Literal, required_argument_builder::Argument};
9use crate::{
10 context::CommandContext,
11 errors::CommandSyntaxError,
12 modifier::RedirectModifier,
13 tree::{Command, CommandNode},
14};
15
16#[derive(Debug)]
17pub enum ArgumentBuilderType<S> {
18 Literal(Literal),
19 Argument(Argument<S>),
20}
21impl<S> Clone for ArgumentBuilderType<S> {
22 fn clone(&self) -> Self {
23 match self {
24 ArgumentBuilderType::Literal(literal) => ArgumentBuilderType::Literal(literal.clone()),
25 ArgumentBuilderType::Argument(argument) => {
26 ArgumentBuilderType::Argument(argument.clone())
27 }
28 }
29 }
30}
31
32#[derive(Clone)]
34pub struct ArgumentBuilder<S> {
35 arguments: CommandNode<S>,
36
37 command: Command<S>,
38 requirement: Arc<dyn Fn(&S) -> bool + Send + Sync>,
39 target: Option<Arc<RwLock<CommandNode<S>>>>,
40
41 forks: bool,
42 modifier: Option<Arc<RedirectModifier<S>>>,
43}
44
45impl<S> ArgumentBuilder<S> {
47 pub fn new(value: ArgumentBuilderType<S>) -> Self {
48 Self {
49 arguments: CommandNode {
50 value,
51 ..Default::default()
52 },
53 command: None,
54 requirement: Arc::new(|_| true),
55 forks: false,
56 modifier: None,
57 target: None,
58 }
59 }
60
61 pub fn then(self, argument: ArgumentBuilder<S>) -> Self {
70 self.then_built(argument.build())
71 }
72
73 pub fn then_built(mut self, argument: CommandNode<S>) -> Self {
77 self.arguments.add_child(&Arc::new(RwLock::new(argument)));
78 self
79 }
80
81 pub fn executes<F>(mut self, f: F) -> Self
92 where
93 F: Fn(&CommandContext<S>) -> i32 + Send + Sync + 'static,
94 {
95 self.command = Some(Arc::new(move |ctx: &CommandContext<S>| Ok(f(ctx))));
96 self
97 }
98
99 pub fn executes_result<F>(mut self, f: F) -> Self
102 where
103 F: Fn(&CommandContext<S>) -> Result<i32, CommandSyntaxError> + Send + Sync + 'static,
104 {
105 self.command = Some(Arc::new(f));
106 self
107 }
108
109 pub fn requires<F>(mut self, requirement: F) -> Self
126 where
127 F: Fn(&S) -> bool + Send + Sync + 'static,
128 {
129 self.requirement = Arc::new(requirement);
130 self
131 }
132
133 pub fn redirect(self, target: Arc<RwLock<CommandNode<S>>>) -> Self {
134 self.forward(target, None, false)
135 }
136
137 pub fn fork(
138 self,
139 target: Arc<RwLock<CommandNode<S>>>,
140 modifier: Arc<RedirectModifier<S>>,
141 ) -> Self {
142 self.forward(target, Some(modifier), true)
143 }
144
145 pub fn forward(
146 mut self,
147 target: Arc<RwLock<CommandNode<S>>>,
148 modifier: Option<Arc<RedirectModifier<S>>>,
149 fork: bool,
150 ) -> Self {
151 if !self.arguments.children.is_empty() {
152 panic!("Cannot forward a node with children");
153 }
154 self.target = Some(target);
155 self.modifier = modifier;
156 self.forks = fork;
157 self
158 }
159
160 pub fn arguments(&self) -> &CommandNode<S> {
161 &self.arguments
162 }
163
164 pub fn build(self) -> CommandNode<S> {
167 let mut result = CommandNode {
168 value: self.arguments.value,
169 command: self.command,
170 requirement: self.requirement,
171 redirect: self.target,
172 modifier: self.modifier,
173 forks: self.forks,
174 arguments: Default::default(),
175 children: Default::default(),
176 literals: Default::default(),
177 };
178
179 for argument in self.arguments.children.values() {
180 result.add_child(argument);
181 }
182
183 result
184 }
185}
186
187impl<S> Debug for ArgumentBuilder<S> {
188 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189 f.debug_struct("ArgumentBuilder")
190 .field("arguments", &self.arguments)
191 .field("target", &self.target)
194 .field("forks", &self.forks)
195 .finish()
197 }
198}