Skip to main content

runx_cli/
cli_args.rs

1use std::ffi::OsString;
2
3pub fn os_arg<'a>(args: &'a [OsString], index: usize, command: &str) -> Result<&'a str, String> {
4    args.get(index)
5        .and_then(|arg| arg.to_str())
6        .ok_or_else(|| format!("{command} arguments must be UTF-8"))
7}
8
9pub fn split_flag(token: &str) -> (&str, Option<&str>) {
10    token
11        .split_once('=')
12        .map_or((token, None), |(flag, value)| (flag, Some(value)))
13}
14
15pub fn flag_value(
16    args: &[OsString],
17    index: usize,
18    flag: &str,
19    inline_value: Option<&str>,
20    command: &str,
21) -> Result<(String, usize), String> {
22    if let Some(value) = inline_value {
23        return Ok((value.to_owned(), index + 1));
24    }
25    let value = os_arg(args, index + 1, command).map_err(|_| format!("{flag} requires a value"))?;
26    if value.starts_with("--") {
27        return Err(format!("{flag} requires a value"));
28    }
29    Ok((value.to_owned(), index + 2))
30}
31
32pub fn optional_flag_value(
33    args: &[OsString],
34    index: usize,
35    inline_value: Option<&str>,
36    command: &str,
37) -> Result<(Option<String>, usize), String> {
38    if let Some(value) = inline_value {
39        return Ok((Some(value.to_owned()), index + 1));
40    }
41    let Some(value) = args.get(index + 1).and_then(|arg| arg.to_str()) else {
42        return Ok((None, index + 1));
43    };
44    if value.starts_with('-') {
45        return Ok((None, index + 1));
46    }
47    os_arg(args, index + 1, command)?;
48    Ok((Some(value.to_owned()), index + 2))
49}
50
51pub fn optional_flag_value_or(
52    args: &[OsString],
53    index: usize,
54    inline_value: Option<&str>,
55    default_value: &str,
56    command: &str,
57) -> Result<(String, usize), String> {
58    if let Some(value) = inline_value {
59        if value.is_empty() {
60            return Ok((default_value.to_owned(), index + 1));
61        }
62        return Ok((value.to_owned(), index + 1));
63    }
64    match args.get(index + 1).and_then(|arg| arg.to_str()) {
65        Some(value) if !value.starts_with("--") => {
66            os_arg(args, index + 1, command)?;
67            Ok((value.to_owned(), index + 2))
68        }
69        _ => Ok((default_value.to_owned(), index + 1)),
70    }
71}