CLI фреймворк для Rust: Clap — мощный и удобный инструмент для создания консольных приложений

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Что такое Clap и зачем он нужен?

В мире системного программирования Rust зарекомендовал себя как язык, сочетающий производительность C/C++ с безопасностью памяти. Однако при создании консольных утилит разработчики часто сталкиваются с рутинной задачей парсинга аргументов командной строки. Библиотека Clap (Command Line Argument Parser) — это самый популярный и функциональный CLI фреймворк для Rust, который берёт на себя всю работу по обработке флагов, опций и подкоманд.

Clap позволяет:

  • Автоматически генерировать справку (--help) и версию (--version);
  • Обрабатывать позиционные аргументы, именованные опции и флаги;
  • Создавать вложенные подкоманды (как в git или cargo);
  • Валидировать типы данных и проверять обязательность аргументов;
  • Работать с автодополнением для оболочек Bash, Zsh, Fish и PowerShell.

Благодаря мощному макросу derive и декларативному API, Clap сокращает объём кода в 5–10 раз по сравнению с ручным парсингом. Библиотека поддерживает как простые утилиты, так и сложные интерфейсы с десятками опций.

Установка Clap в проект Rust

Добавьте зависимость в Cargo.toml:

[dependencies]
clap = { version = "4.5", features = ["derive"] }

Флаг features = ["derive"] включает поддержку макросов — это рекомендуемый способ для большинства проектов. Для минималистичных утилит можно использовать только builder API (без derive).

Пример 1: Простейший парсер с макросом derive

Создадим утилиту, которая принимает имя пользователя и опциональный флаг приветствия:

use clap::Parser;

#[derive(Parser)]
#[command(name = "greet")]
#[command(about = "Простое приветствие", long_about = None)]
struct Cli {
    /// Имя пользователя
    name: String,

    /// Вывести приветствие в верхнем регистре
    #[arg(short, long)]
    uppercase: bool,
}

fn main() {
    let cli = Cli::parse();

    let greeting = format!("Привет, {}!", cli.name);
    if cli.uppercase {
        println!("{}", greeting.to_uppercase());
    } else {
        println!("{}", greeting);
    }
}

Запустите программу:

$ cargo run -- Мир
Привет, Мир!

$ cargo run -- Мир --uppercase
ПРИВЕТ, МИР!

$ cargo run -- --help
# Автоматически сгенерированная справка

Пример 2: Опции с типами и значениями по умолчанию

Clap автоматически конвертирует строки в нужные типы (числа, перечисления, даты). Добавим опцию для указания количества повторений:

use clap::Parser;

#[derive(Parser)]
#[command(name = "repeat")]
struct Cli {
    /// Текст для повторения
    text: String,

    /// Количество повторений (по умолчанию 1)
    #[arg(short, long, default_value_t = 1)]
    count: u32,
}

fn main() {
    let cli = Cli::parse();
    for _ in 0..cli.count {
        println!("{}", cli.text);
    }
}

Теперь можно выполнить:

$ cargo run -- "Rust" -c 3
Rust
Rust
Rust

Пример 3: Подкоманды (субкоманды) — как в Git

Создадим мини-утилиту для управления задачами (todo list) с командами add, list и done:

use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command(name = "todo")]
#[command(about = "Менеджер задач")]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Добавить новую задачу
    Add {
        /// Текст задачи
        task: String,
    },
    /// Показать все задачи
    List,
    /// Отметить задачу как выполненную
    Done {
        /// ID задачи
        id: u32,
    },
}

fn main() {
    let cli = Cli::parse();

    match &cli.command {
        Commands::Add { task } => println!("Добавлена задача: {}", task),
        Commands::List => println!("Список задач (пока пуст)"),
        Commands::Done { id } => println!("Задача #{} выполнена!", id),
    }
}

Рекомендаций