mddd_std/runners/
node.rs

1use std::mem;
2use crate::constants::HELP_KEYS;
3use crate::runners::helper::make_node_help;
4use crate::runners::main_executor;
5use crate::utils::print_n_exit;
6
7use mddd_traits::IRunner;
8
9pub struct NodeRunner {
10    description: String,
11    default_params: Vec<String>,
12    runners: Vec<(String, Box<dyn IRunner>)>,
13}
14
15impl NodeRunner {
16    pub fn new(description: impl ToString) -> Self {
17        Self {
18            description: description.to_string(),
19            default_params: Default::default(),
20            runners: Vec::new(),
21        }
22    }
23
24    pub fn add(mut self, cmd: impl ToString, runner: impl IRunner + 'static) -> Self {
25        self.runners.push((cmd.to_string(), Box::new(runner)));
26        self
27    }
28
29    pub fn add_box(mut self, cmd: impl ToString, runner: Box<dyn IRunner>) -> Self {
30        self.runners.push((cmd.to_string(), runner));
31        self
32    }
33
34    pub fn set_default_params<T: ToString>(mut self, params: &[T]) -> Self {
35        self.default_params = params.iter()
36            .map(|p|p.to_string())
37            .collect();
38        self
39    }
40
41    pub fn run(self) {
42        main_executor::run(self)
43    }
44
45    fn execute_command(&mut self, prefix: &str, cmd: &str, args: &[&str]) {
46        let found = self.runners.iter_mut().find(|(key, _)| key == cmd);
47        let child = match found {
48            Some((_, val)) => val,
49            None => print_n_exit(&format!("Invalid command: {}", cmd)),
50        };
51        let prefix = format!("{} {}", prefix, cmd);
52        child.execute(&prefix, args)
53    }
54
55    fn execute_without_args(&mut self, prefix: &str) {
56        if self.default_params.is_empty() {
57            self.execute_with_args(prefix, &[HELP_KEYS[0]])
58        } else {
59            let args = mem::take(&mut self.default_params);
60            let ptr_args = args.iter()
61                .map(|s| -> &str {s})
62                .collect::<Vec<_>>();
63            self.execute_with_args(prefix, &ptr_args)
64        }
65    }
66
67    fn execute_with_args(&mut self, prefix: &str, args: &[&str]) {
68        if HELP_KEYS.contains(&args[0]) {
69            let help = make_node_help(prefix, &self.short_description(), &self.runners);
70            println!("{}", help);
71        } else {
72            self.execute_command(prefix, args[0], &args[1..])
73        }
74    }
75}
76
77impl IRunner for NodeRunner {
78    fn short_description(&self) -> String {
79        self.description.clone()
80    }
81
82    fn execute(&mut self, prefix: &str, args: &[&str]) {
83        if args.is_empty() {
84            self.execute_without_args(prefix)
85        } else {
86            self.execute_with_args(prefix, args)
87        }
88    }
89}