Rust: парсить вводимую пользователем строку с хлопком для программирования командной строки - PullRequest
0 голосов
/ 27 мая 2020

Я хотел бы создать командную строку, которая использует хлопок для анализа ввода. Лучшее, что я могу придумать, - это al oop, который запрашивает у пользователя ввод, разбивает его с помощью регулярного выражения и строит Ve c, который каким-то образом передает на

loop {
    // Print command prompt and get command
    print!("> "); io::stdout().flush().expect("Couldn't flush stdout");

    let mut input = String::new(); // Take user input (to be parsed as clap args)
    io::stdin().read_line(&mut input).expect("Error reading input.");
    let args = WORD.captures_iter(&input)
           .map(|cap| cap.get(1).or(cap.get(2)).unwrap().as_str())
           .collect::<Vec<&str>>();

    let matches = App::new("MyApp")
        // ... Process Clap args/subcommands
    .get_matches(args); //match arguments from CLI args variable
}

В основном, я ' Мне интересно, есть ли способ заставить Клапа использовать заранее заданный список аргументов?

Ответы [ 2 ]

1 голос
/ 27 мая 2020

Как говорит @mcarton, программам командной строки аргументы передаются в виде массива, а не строки. Оболочка разделяет исходную командную строку (с учетом кавычек, расширения переменных и т. Д. c).

Если ваши требования просты, вы можете просто разделить строку на пробелы и передать это в Clap. Или, если вы хотите уважать строки в кавычках, вы можете использовать shellwords для их анализа:

let words = shellwords::split(input)?;
let matches = App::new("MyApp")
    // ... command line argument options
    .get_matches_from(words);
0 голосов
/ 24 июня 2020

Вот как я закончил работу:

Во-первых, я поместил всю свою основную функцию в loop, чтобы она могла получать команды и оставаться в CLI.

Затем я получил ввод через stdin и разделил аргументы

// Print command prompt and get command
print!("> ");
io::stdout().flush().expect("Couldn't flush stdout");
let mut input = String::new();
io::stdin().read_line(&mut input).expect("Error reading input.");
let args = WORD.captures_iter(&input)
           .map(|cap| cap.get(1).or(cap.get(2)).unwrap().as_str())
           .collect::<Vec<&str>>();

Затем я использовал Clap для анализа, вроде как @ harmi c предложил

let matches = App::new("MyApp")
    // ... command line argument options
    .get_matches_from(words);

и использовал subcommands вместо arguments.

например,

.subcommand(SubCommand::with_name("list")
    .help("Print namespaces currently tracked in the database."))

Весь файл здесь для любопытных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...