Skip to content

Commit 920ab51

Browse files
committed
Use pico-args for arg parsing
I'm not sure if this is really much better than it was before, it would be handy for the parse_args func to do all the validation and pass back a consistent error type with a possibility for some other errors wrapped up in some of the variants. I ran the tests (not sure if they use the arg parsing or not :D), and tested with a couple of arg combos and it seems to work. Regardless of caveats, feel free to merge or close this PR, pico-args is just one option for arg-parsing. This code could also use improvement, I'm happy to incorporate feedback.
1 parent fb671ab commit 920ab51

3 files changed

Lines changed: 37 additions & 47 deletions

File tree

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ serde_json = "1.0.42"
1616
toml = "0.5.5"
1717
dbus = {version = "*", optional = true}
1818
shlex = "0.1.1"
19+
pico-args = "0.3"
1920

2021
[features]
2122
dbus_support = ["dbus"]
2223
linux_eventfd = []
23-
cgroups = []
24+
cgroups = []

src/bin/rustysd.rs

Lines changed: 28 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -201,67 +201,49 @@ fn start_signal_handler_thread(
201201
handle
202202
}
203203

204+
const USAGE: &'static str = "Usage: rustysd [-c | --config PATH] [-d | --dry-run] [-h | --help]";
205+
204206
#[derive(Default)]
205207
struct CliArgs {
206208
conf_path: Option<std::path::PathBuf>,
207209
dry_run: bool,
208210
show_help: bool,
209-
unknown_arg: Option<String>
211+
free_args: Vec<String>
210212
}
211213

212-
fn parse_args() -> CliArgs {
213-
let args = std::env::args().collect::<Vec<_>>();
214-
// ignore exec name
215-
let args = &args[1..];
216-
217-
let mut cli_args = CliArgs::default();
218-
let mut idx = 0;
219-
while idx < args.len() {
220-
match args[idx].as_str() {
221-
"-c" | "--config" => {
222-
if args.len() < idx {
223-
unrecoverable_error(format!("config flag set but no path given"));
224-
} else {
225-
let path_str = args[idx + 1].clone();
226-
let p = std::path::PathBuf::from(path_str);
227-
if !p.exists() {
228-
unrecoverable_error(format!("config path given that does not exist"));
229-
}
230-
if !p.is_dir() {
231-
unrecoverable_error(format!("config path given that is not a directory"));
232-
}
233-
cli_args.conf_path = Some(p);
234-
idx += 2;
235-
}
236-
}
237-
"-d" | "--dry-run" => {
238-
cli_args.dry_run = true;
239-
idx += 1;
240-
}
241-
"-h" | "--help" => {
242-
cli_args.show_help = true;
243-
idx += 1;
244-
}
245-
unknown => {
246-
cli_args.unknown_arg = Some(unknown.to_string());
247-
break;
248-
}
249-
}
250-
}
251-
cli_args
214+
fn parse_args() -> Result<CliArgs, pico_args::Error> {
215+
let mut args = pico_args::Arguments::from_env();
216+
Ok(CliArgs {
217+
conf_path: args.opt_value_from_str(["-c", "--config"])?,
218+
dry_run: args.contains(["-d", "--dry-run"]),
219+
show_help: args.contains(["-h", "--help"]),
220+
free_args: args.free()?,
221+
})
252222
}
253223

254224
fn main() {
255225
pid1_specific_setup();
256226

257-
let cli_args = parse_args();
227+
let cli_args = parse_args()
228+
.unwrap_or_else(|e| {
229+
unrecoverable_error(e.to_string());
230+
unreachable!();
231+
});
232+
233+
if let Some(path) = &cli_args.conf_path {
234+
if !path.exists() {
235+
unrecoverable_error(format!("config path given that does not exist"));
236+
}
237+
if !path.is_dir() {
238+
unrecoverable_error(format!("config path given that is not a directory"));
239+
}
240+
}
258241

259-
let usage = "Usage: rustysd [-c | --config PATH] [-d | --dry-run] [-h | --help]";
260242
if cli_args.show_help {
261-
println!("{}", usage);
243+
println!("{}", USAGE);
262244
std::process::exit(0);
263-
} else if let Some(unknown) = cli_args.unknown_arg {
264-
unrecoverable_error(format!("{}\n\nUnknown cli arg: {}", usage, unknown));
245+
} else if cli_args.free_args.len() > 0 {
246+
unrecoverable_error(format!("{}\n\nUnknown cli arg(s): {:?}", USAGE, cli_args.free_args));
265247
}
266248

267249
let (log_conf, conf) = config::load_config(&cli_args.conf_path);

0 commit comments

Comments
 (0)