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 parse args, generate help/usage tự động.
- Có thể định nghĩa flag (
-v), option (--file <path>), và subcommand (init,serve).
Clap cho phép derive từ struct (#[derive(Parser)]) để map arg → field, gọn và dễ maintain.
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
- Basic: Thêm flag
--verboseđể in log chi tiết. - Intermediate: Thêm option
--file <path>để đọc file và in số ký tự. - Challenge: Thêm subcommand
genđể sinh ID ngẫu nhiên (dùngrandcrate).
🐞 Common Pitfalls & Debugging Tips
- Quên bật feature
derivetrong 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+)
- 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
- 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
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.