clap CLI

Установка

Установить вместе с допом derive, чтобы добавлять clap как признак (trait) у структур данных.

cargo add clap -F derive

Как использовать

Добавка clap позволяет парсить аргументы командной строки, а также добавляет ключи “-h” и “–help” для помощи без кода:

use clap::Parser;

#[derive(Parser, Debug)]
struct Args {
    arg1: String,
    arg2: usize,
}

fn main() {
    let args = Args::parse();
    println!("{:?}", args)
}

При запуске данная программа требует 2 аргумента, притом второй обязательно числом.

Добавление описаний

Имя программы и версия вносятся отдельным признаком. Доп. поля описания вносятся с помощью спец. комментариев ///:

use clap::Parser;

#[derive(Parser, Debug)]
#[command(author = "Author Name", version, about)]
/// A very simple CLI parser
struct Args {
    /// Text argument option
    arg1: String,
    /// Number argument option
    arg2: usize,
}

fn main() {
    let args = Args::parse();
    println!("{:?}", args)
}

Добавка флагов

Флаги добавляем с помощью аннотации #[arg(short, long)] для короткого и длинного именования флага. Если у 2-х флагов одинаковая первая буква, можно указать вручную их короткую версию. Короткая версия не может быть String, можно только 1 char.

<..>
struct Args {
    #[arg(short = 'a', long)]
    /// Text argument option
    arg1: String,
    
    #[arg(short = 'A', long)]
    /// Number argument option
    arg2: usize,
}
<..>

Необязательные флаги

Для отметки аргумента как необязательного достаточно указать его тип как Option<тип> и в скобках исходный тип данных:

struct Args {
    #[arg(short = 'a', long)]
    /// Text argument option
    arg1: String,
    
    #[arg(short = 'A', long)]
    /// Number argument option
    arg2: Option<usize>,
}

Такой подход потребует обработать ситуацию, когда в arg2 ничего нет. Вместо так делать, можно указать значение по умолчанию:

struct Args {
    #[arg(short = 'a', long)]
    /// Text argument option
    arg1: String,
    
    #[arg(default_value_t=usize::MAX, short = 'A', long)]
    /// Number argument option
    arg2: usize,
}

Теперь arg2 по умолчанию будет равен максимальному числу usize, если не указано иное.

Валидация введённых значений

В случае аргумента-строки есть возможность ввести пустую строку из пробелов " ". Для исключения таких вариантов, вводится функция валидации и её вызов:

use clap::Parser;

#[derive(Parser, Debug)]
#[command(author = "Author Name", version, about)]
/// A very simple CLI parser
struct Args {
    #[arg(value_parser = validate_argument_name, short = 'a', long)]
    /// Text argument option
    arg1: String,
    #[arg(default_value_t=usize::MAX, short = 'A', long)]
    /// Number argument option
    arg2: usize,
}

fn validate_argument_name(name: &str) -> Result<String, String> {
    if name.trim().len() != name.len() {
        Err(String::from(
            "строка не должна начинаться или заканчиваться пробелами",
        ))
    } else {
        Ok(name.to_string())
    }
}

fn main() {
    let args = Args::parse();
    println!("{:?}", args)
}

Теперь при попытке вызвать программу tiny-clapper -- -a " " будет показана ошибка валидации.