1use std::rc::Rc;
12
13use super::{Completion, Parser};
14use super::constants::*;
15use tokenizer::Token;
16
17pub enum Node {
19 Command(CommandNode),
21 Parameter(ParameterNode),
23 ParameterName(ParameterNameNode),
25 Root(RootNode),
27}
28
29pub trait NodeOps {
31 fn accept<'text>(&self, parser: &mut Parser<'text>, token: Token, node_ref: &Rc<Node>);
35
36 fn acceptable(&self, parser: &Parser, node_ref: &Rc<Node>) -> bool;
47
48 fn complete<'text>(&self, token: Option<Token<'text>>) -> Completion<'text>;
62
63 fn matches(&self, parser: &Parser, token: Token) -> bool;
75}
76
77pub struct TreeNode {
79 pub name: String,
81 pub help_symbol: String,
85 pub help_text: String,
87 pub hidden: bool,
89 pub priority: i32,
91 pub repeatable: bool,
94 pub repeat_marker: Option<Rc<Node>>,
96 pub successors: Vec<Rc<Node>>,
98}
99
100pub struct RootNode {
102 pub node: TreeNode,
106}
107
108pub struct CommandNode {
117 pub node: TreeNode,
121 pub handler: Option<fn(node: &Node) -> ()>,
123 pub parameters: Vec<Rc<Node>>,
125 pub wrapped_root: Option<Rc<Node>>,
127}
128
129pub struct ParameterNameNode {
132 pub node: TreeNode,
136 pub parameter: Rc<Node>,
138}
139
140pub struct ParameterNode {
142 pub node: TreeNode,
146 pub required: bool,
149 pub kind: ParameterKind,
151}
152
153impl PartialEq for Node {
154 fn eq(&self, other: &Self) -> bool {
156 self as *const _ == other as *const _
157 }
158}
159
160impl Node {
166 pub fn node(&self) -> &TreeNode {
170 match *self {
171 Node::Command(ref command) => &command.node,
172 Node::Parameter(ref parameter) => ¶meter.node,
173 Node::ParameterName(ref name) => &name.node,
174 Node::Root(ref root) => &root.node,
175 }
176 }
177
178 pub fn successors(&self) -> &Vec<Rc<Node>> {
180 match *self {
181 Node::Root(ref root) => &root.node.successors,
182 _ => &self.node().successors,
183 }
184 }
185}
186
187impl NodeOps for Node {
188 fn accept<'text>(&self, parser: &mut Parser<'text>, token: Token, node_ref: &Rc<Node>) {
189 match *self {
190 Node::Command(ref command) => command.accept(parser, token, node_ref),
191 Node::Parameter(ref parameter) => parameter.accept(parser, token, node_ref),
192 Node::ParameterName(ref name) => name.accept(parser, token, node_ref),
193 Node::Root(ref root) => root.accept(parser, token, node_ref),
194 }
195 }
196
197 fn acceptable(&self, parser: &Parser, node_ref: &Rc<Node>) -> bool {
198 match *self {
199 Node::Command(ref command) => command.acceptable(parser, node_ref),
200 Node::Parameter(ref parameter) => parameter.acceptable(parser, node_ref),
201 Node::ParameterName(ref name) => name.acceptable(parser, node_ref),
202 Node::Root(ref root) => root.acceptable(parser, node_ref),
203 }
204 }
205
206 fn complete<'text>(&self, token: Option<Token<'text>>) -> Completion<'text> {
207 match *self {
208 Node::Command(ref command) => command.complete(token),
209 Node::Parameter(ref parameter) => parameter.complete(token),
210 Node::ParameterName(ref name) => name.complete(token),
211 Node::Root(ref root) => root.complete(token),
212 }
213 }
214
215 fn matches(&self, parser: &Parser, token: Token) -> bool {
216 match *self {
217 Node::Command(ref command) => command.matches(parser, token),
218 Node::Parameter(ref parameter) => parameter.matches(parser, token),
219 Node::ParameterName(ref name) => name.matches(parser, token),
220 Node::Root(ref root) => root.matches(parser, token),
221 }
222 }
223}
224
225impl RootNode {
226 pub fn new(successors: Vec<Rc<Node>>) -> Self {
228 RootNode {
229 node: TreeNode {
230 name: "__root__".to_string(),
231 help_symbol: "".to_string(),
232 help_text: "".to_string(),
233 hidden: false,
234 priority: PRIORITY_DEFAULT,
235 repeat_marker: None,
236 repeatable: false,
237 successors: successors,
238 },
239 }
240 }
241}
242
243impl NodeOps for RootNode {
246 fn accept<'text>(&self, _parser: &mut Parser<'text>, _token: Token, _node_ref: &Rc<Node>) {}
247
248 fn acceptable(&self, _parser: &Parser, _node_ref: &Rc<Node>) -> bool {
249 false
250 }
251
252 fn complete<'text>(&self, _token: Option<Token<'text>>) -> Completion<'text> {
254 panic!("BUG: Can not complete a root node.");
255 }
256
257 fn matches(&self, _parser: &Parser, _token: Token) -> bool {
259 panic!("BUG: Can not match a root node.");
260 }
261}
262
263impl CommandNode {
264 pub fn new(name: &str,
266 help_text: Option<&str>,
267 hidden: bool,
268 priority: i32,
269 successors: Vec<Rc<Node>>,
270 handler: Option<fn(node: &Node) -> ()>,
271 parameters: Vec<Rc<Node>>)
272 -> Self {
273 CommandNode {
274 node: TreeNode {
275 name: name.to_string(),
276 help_symbol: name.to_string(),
277 help_text: help_text.unwrap_or("Command").to_string(),
278 hidden: hidden,
279 priority: priority,
280 repeat_marker: None,
281 repeatable: false,
282 successors: successors,
283 },
284 handler: handler,
285 parameters: parameters,
286 wrapped_root: None,
287 }
288 }
289}
290
291impl NodeOps for CommandNode {
292 fn accept<'text>(&self, parser: &mut Parser<'text>, _token: Token, node_ref: &Rc<Node>) {
294 if self.handler.is_some() {
295 parser.commands.push(node_ref.clone())
296 }
297 }
298
299 fn acceptable(&self, parser: &Parser, node_ref: &Rc<Node>) -> bool {
300 !parser.nodes.contains(node_ref)
301 }
302
303 fn complete<'text>(&self, token: Option<Token<'text>>) -> Completion<'text> {
304 Completion::new(self.node.help_symbol.clone(),
305 self.node.help_text.clone(),
306 token,
307 true,
308 vec![&self.node.name],
309 vec![])
310 }
311
312 fn matches(&self, _parser: &Parser, token: Token) -> bool {
313 self.node.name.starts_with(token.text)
314 }
315}
316
317impl ParameterNameNode {
318 pub fn new(name: &str,
320 hidden: bool,
321 priority: i32,
322 successors: Vec<Rc<Node>>,
323 repeatable: bool,
324 repeat_marker: Option<Rc<Node>>,
325 parameter: Rc<Node>)
326 -> Self {
327 let param_node = ¶meter.node();
328 let help_text = param_node.help_text.clone();
329 let help_symbol = name.to_string() + " " + param_node.help_symbol.as_str();
330 ParameterNameNode {
331 node: TreeNode {
332 name: name.to_string(),
333 help_symbol: help_symbol,
334 help_text: help_text,
335 hidden: hidden,
336 priority: priority,
337 repeat_marker: repeat_marker,
338 repeatable: repeatable,
339 successors: successors,
340 },
341 parameter: parameter.clone(),
342 }
343 }
344}
345
346impl NodeOps for ParameterNameNode {
347 fn accept<'text>(&self, _parser: &mut Parser<'text>, _token: Token, _node_ref: &Rc<Node>) {}
349
350 fn acceptable(&self, parser: &Parser, node_ref: &Rc<Node>) -> bool {
351 if self.node.repeatable {
352 return true;
353 }
354 !parser.nodes.contains(node_ref) &&
355 match self.node.repeat_marker {
356 None => true,
357 Some(ref n) => !parser.nodes.contains(n),
358 }
359 }
360
361 fn complete<'text>(&self, token: Option<Token<'text>>) -> Completion<'text> {
362 Completion::new(self.node.help_symbol.clone(),
363 self.node.help_text.clone(),
364 token,
365 true,
366 vec![&self.node.name],
367 vec![])
368 }
369
370 fn matches(&self, _parser: &Parser, token: Token) -> bool {
371 self.node.name.starts_with(token.text)
372 }
373}
374
375impl ParameterNode {
376 pub fn new(name: &str,
378 help_text: Option<&str>,
379 hidden: bool,
380 priority: i32,
381 successors: Vec<Rc<Node>>,
382 repeatable: bool,
383 repeat_marker: Option<Rc<Node>>,
384 kind: ParameterKind,
385 required: bool)
386 -> Self {
387 let help_symbol = if repeatable {
388 String::from("<") + name + ">..."
389 } else {
390 String::from("<") + name + ">"
391 };
392 let default_help_text = match kind {
393 ParameterKind::Flag => "Flag",
394 ParameterKind::Named | ParameterKind::Simple => "Parameter",
395 };
396 let help_text = help_text.unwrap_or(default_help_text).to_string();
397 ParameterNode {
398 node: TreeNode {
399 name: name.to_string(),
400 help_symbol: help_symbol,
401 help_text: help_text,
402 hidden: hidden,
403 priority: priority,
404 repeat_marker: repeat_marker,
405 repeatable: repeatable,
406 successors: successors,
407 },
408 kind: kind,
409 required: required,
410 }
411 }
412}
413
414impl NodeOps for ParameterNode {
415 fn accept<'text>(&self, parser: &mut Parser<'text>, token: Token, _node_ref: &Rc<Node>) {
417 if self.node.repeatable {
418 unimplemented!();
419 } else {
420 parser.parameters.insert(self.node.name.clone(), token.text.to_string());
421 }
422 }
423
424 fn acceptable(&self, parser: &Parser, node_ref: &Rc<Node>) -> bool {
425 if self.node.repeatable {
426 return true;
427 }
428 !parser.nodes.contains(node_ref) &&
429 match self.node.repeat_marker {
430 None => true,
431 Some(ref n) => !parser.nodes.contains(n),
432 }
433 }
434
435 fn complete<'text>(&self, token: Option<Token<'text>>) -> Completion<'text> {
438 match self.kind {
439 ParameterKind::Named | ParameterKind::Simple => {
440 Completion::new(self.node.help_symbol.clone(),
441 self.node.help_text.clone(),
442 token,
443 true,
444 vec![],
445 vec![])
446 }
447 ParameterKind::Flag => {
448 Completion::new(self.node.help_symbol.clone(),
449 self.node.help_text.clone(),
450 token,
451 true,
452 vec![&self.node.name],
453 vec![])
454 }
455 }
456 }
457
458 fn matches(&self, _parser: &Parser, token: Token) -> bool {
459 match self.kind {
460 ParameterKind::Named | ParameterKind::Simple => true,
461 ParameterKind::Flag => self.node.name.starts_with(token.text),
462 }
463 }
464}