Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Lesson 7 — Building a CLI Tool with Clap


🎯 Learning Objectives

  • Biết cách tạo CLI tool bằng crate clap.
  • Hiểu cách định nghĩa tham số, cờ (flag), và subcommand.
  • Thực hành viết CLI nhỏ, sẵn sàng tái sử dụng trong production.

✅ Explanation & Key Concepts

Clap Basics

  • Clap parse args, generate help/usage tự động.
  • Có thể định nghĩa flag (-v), option (--file <path>), và subcommand (init, serve).

Ergonomics

Clap cho phép derive từ struct (#[derive(Parser)]) để map arg → field, gọn và dễ maintain.

Production Ready

Clap được dùng rộng rãi, tự động validate input, hiển thị help/--version, rất phù hợp cho tool thực tế.


💻 Example Implementation

Cargo.toml

[package]
name = "lesson07_cli_clap"
version = "0.1.0"
edition = "2024"

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

src/main.rs


// cargo-deps: clap="4"
use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command(name = "mycli", version, about = "Example CLI Tool", long_about = None)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Print greeting
    Hello {
        /// Name to greet
        name: String,
    },
    /// Add two numbers
    Add {
        a: i32,
        b: i32,
    },
}

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

    match &cli.command {
        Commands::Hello { name } => {
            println!("Hi, {}!", name);
        }
        Commands::Add { a, b } => {
            println!("{} + {} = {}", a, b, a + b);
        }
    }
}

Chạy thử:

cargo run -- hello dp
cargo run -- add 5 7

🛠️ Hands-on Exercises

  1. Basic: Thêm flag --verbose để in log chi tiết.
  2. Intermediate: Thêm option --file <path> để đọc file và in số ký tự.
  3. Challenge: Thêm subcommand gen để sinh ID ngẫu nhiên (dùng rand crate).

🐞 Common Pitfalls & Debugging Tips

Common Pitfalls

  • Quên bật feature derive trong Cargo.toml.
  • Nhầm lẫn giữa option (có giá trị) và flag (boolean).
  • Không test với nhiều input → dễ miss case invalid.

🔄 Migration Notes (Rust 2024+)

Migration Guidance

  • Clap 4.x stable, tương thích Rust 2024.
  • Nên dùng derive API thay vì builder API cho code gọn.
  • Với tool lớn, chia subcommand thành module riêng.

📚 References


❓ Q&A — Common Questions

Q1. Clap có nặng không, có ảnh hưởng performance?

  • Clap chỉ parse args khi start chương trình, chi phí rất nhỏ so với runtime.

Q2. Khác biệt giữa derive API và builder API?

  • Derive API ngắn gọn, dễ maintain; builder API linh hoạt hơn cho cấu hình phức tạp.

Q3. Có thể test CLI dễ không?

  • Có, Clap hỗ trợ Command::try_get_matches_from để mock args trong unit test.

📖 Glossary of Terms

Key Terms

  • Flag: tùy chọn boolean (-v).
  • Option: tùy chọn có giá trị (--file <path>).
  • Subcommand: lệnh con (init, serve).
  • Parser derive: cách map arg → struct field.

🌿 Wisdom Note

Đạo Đức Kinh — Chương 70

Ngô ngôn hạ dị tri, hạ dị hành.

My words are easy to understand and easy to practice.

Clap cũng vậy: định nghĩa gọn, tự động parse, giúp CLI dễ hiểu và dễ dùng.