]> git.proxmox.com Git - proxmox.git/blame - proxmox-api/src/cli.rs
clippy fixups
[proxmox.git] / proxmox-api / src / cli.rs
CommitLineData
1819b194
DM
1//! Tools to create command line parsers
2//!
3//! This crate provides convenient helpers to create command line
4//! parsers using Schema definitions.
5//!
6//! ## Features
7//!
8//! - Use declarative API schema to define the CLI
9//! - Automatic parameter verification
10//! - Automatically generate documentation and manual pages
11//! - Automatically generate bash completion helpers
12//! - Ability to create interactive commands (using ``rustyline``)
13//! - Supports complex/nested commands
14
15mod environment;
16pub use environment::*;
17
18mod shellword;
19pub use shellword::*;
20
21mod format;
22pub use format::*;
23
24mod completion;
25pub use completion::*;
26
27mod getopts;
28pub use getopts::*;
29
30mod command;
31pub use command::*;
32
33mod readline;
34pub use readline::*;
35
36use std::collections::HashMap;
37
38use crate::ApiMethod;
39
40/// Completion function for single parameters.
41///
42/// Completion functions gets the current parameter value, and should
43/// return a list of all possible values.
44pub type CompletionFunction = fn(&str, &HashMap<String, String>) -> Vec<String>;
45
46/// Define a simple CLI command.
47pub struct CliCommand {
48 /// The Schema definition.
49 pub info: &'static ApiMethod,
50 /// Argument parameter list.
51 ///
52 /// Those parameters are expected to be passed as command line
53 /// arguments in the specified order. All other parameters needs
54 /// to be specified as ``--option <value>`` pairs.
55 pub arg_param: &'static [&'static str],
56 /// Predefined parameters.
57 pub fixed_param: HashMap<&'static str, String>,
58 /// Completion functions.
59 ///
60 /// Each parameter may have an associated completion function,
61 /// which is called by the shell completion handler.
62 pub completion_functions: HashMap<String, CompletionFunction>,
63}
64
65impl CliCommand {
1819b194
DM
66 /// Create a new instance.
67 pub fn new(info: &'static ApiMethod) -> Self {
68 Self {
92ffe4c2
WB
69 info,
70 arg_param: &[],
1819b194
DM
71 fixed_param: HashMap::new(),
72 completion_functions: HashMap::new(),
73 }
74 }
75
76 /// Set argument parameter list.
77 pub fn arg_param(mut self, names: &'static [&'static str]) -> Self {
78 self.arg_param = names;
79 self
80 }
81
82 /// Set fixed parameters.
83 pub fn fixed_param(mut self, key: &'static str, value: String) -> Self {
84 self.fixed_param.insert(key, value);
85 self
86 }
87
88 /// Set completion functions.
92ffe4c2 89 pub fn completion_cb(mut self, param_name: &str, cb: CompletionFunction) -> Self {
1819b194
DM
90 self.completion_functions.insert(param_name.into(), cb);
91 self
92 }
93}
94
95/// Define nested CLI commands.
96pub struct CliCommandMap {
97 /// Each command has an unique name. The map associates names with
98 /// command definitions.
99 pub commands: HashMap<String, CommandLineInterface>,
100}
101
102impl CliCommandMap {
1819b194
DM
103 /// Create a new instance.
104 pub fn new() -> Self {
92ffe4c2
WB
105 Self {
106 commands: HashMap::new(),
107 }
1819b194
DM
108 }
109
110 /// Insert another command.
111 pub fn insert<S: Into<String>>(mut self, name: S, cli: CommandLineInterface) -> Self {
112 self.commands.insert(name.into(), cli);
113 self
114 }
115
116 /// Insert the help command.
117 pub fn insert_help(mut self) -> Self {
92ffe4c2
WB
118 self.commands
119 .insert(String::from("help"), help_command_def().into());
1819b194
DM
120 self
121 }
122
123 fn find_command(&self, name: &str) -> Option<(String, &CommandLineInterface)> {
1819b194
DM
124 if let Some(sub_cmd) = self.commands.get(name) {
125 return Some((name.to_string(), sub_cmd));
126 };
127
128 let mut matches: Vec<&str> = vec![];
129
130 for cmd in self.commands.keys() {
131 if cmd.starts_with(name) {
92ffe4c2
WB
132 matches.push(cmd);
133 }
1819b194
DM
134 }
135
92ffe4c2
WB
136 if matches.len() != 1 {
137 return None;
138 }
1819b194
DM
139
140 if let Some(sub_cmd) = self.commands.get(matches[0]) {
141 return Some((matches[0].to_string(), sub_cmd));
142 };
143
144 None
145 }
146}
147
148/// Define Complex command line interfaces.
149pub enum CommandLineInterface {
150 Simple(CliCommand),
151 Nested(CliCommandMap),
152}
153
154impl From<CliCommand> for CommandLineInterface {
155 fn from(cli_cmd: CliCommand) -> Self {
92ffe4c2 156 CommandLineInterface::Simple(cli_cmd)
1819b194
DM
157 }
158}
159
160impl From<CliCommandMap> for CommandLineInterface {
161 fn from(list: CliCommandMap) -> Self {
162 CommandLineInterface::Nested(list)
163 }
164}