clap
Derive 教程
快速开始
添加 clap derive 依赖
cargo add clap --features derive
预览一个应用程序
use std::path::PathBuf; use clap::{Parser, Subcommand}; #[derive(Parser)] #[command(version, about, long_about = None)] struct Cli { /// 要操作的名字 name: Option<String>, /// 设置自定义配置文件 #[arg(short, long, value_name = "FILE")] config: Option<PathBuf>, /// 开启调试 #[arg(short, long, action = clap::ArgAction::Count)] debug: u8, /// 子命令 #[command(subcommand)] command: Option<Commands>, } #[derive(Subcommand)] enum Commands { /// 测试 Test { /// 列出测试的值 #[arg(short, long)] list: bool, }, } fn main() { let cli = Cli::parse(); // You can check the value provided by positional arguments, or option arguments if let Some(name) = cli.name.as_deref() { println!("Value for name: {name}"); } if let Some(config_path) = cli.config.as_deref() { println!("Value for config: {}", config_path.display()); } // You can see how many times a particular flag or argument occurred // Note, only flags can have multiple occurrences match cli.debug { 0 => println!("Debug mode is off"), 1 => println!("Debug mode is kind of on"), 2 => println!("Debug mode is on"), _ => println!("Don't be crazy"), } // You can check for the existence of subcommands, and if found use their // matches just as you would the top level cmd match &cli.command { Some(Commands::Test { list }) => { if *list { println!("Printing testing lists..."); } else { println!("Not printing testing lists..."); } } None => {} } }
配置 Parser
代码指定
use clap::Parser; #[derive(Parser)] #[command(name = "MyApp")] #[command(version = "1.0")] #[command(about = "Does awesome things", long_about = None)] struct Cli { name: Vec<String>, #[arg(long)] two: String, #[arg(long)] one: String, } fn main() { let cli = Cli::parse(); println!("name: {:?}", cli.name); println!("two: {:?}", cli.two); println!("one: {:?}", cli.one); }
运行程序
$ cargo run -- --help
# 查看帮助信息
Does awesome things
Usage: clap_config --two <TWO> --one <ONE>
Options:
--two <TWO>
--one <ONE>
-h, --help Print help
-V, --version Print version
$ cargo run -- --version
# 查看版本
MyApp 1.0
$ cargo run -- --two=2 --one=1
# 程序输出获取的参数
two: "2"
one: "1"
从 cargo.toml 读取
use clap::Parser; #[derive(Parser)] #[command(name = "MyApp")] #[command(version, about)] struct Cli { #[arg(long)] two: String, #[arg(long)] one: String, } fn main() { let cli = Cli::parse(); println!("two: {:?}", cli.two); println!("one: {:?}", cli.one); }
cargo.toml
[package]
name = "clap_config_from_cargo"
version = "0.1.0"
edition = "2024"
authors = ["hanjian <hanjian@zhouyi.com>"]
description = "A simple CLI app using clap"
[dependencies]
clap = { version = "4.5.53", features = ["derive"] }
运行命令查看
$ cargo run -- --help
A simple CLI app using clap
Usage: clap_config_from_cargo --two <TWO> --one <ONE>
Options:
--two <TWO>
--one <ONE>
-h, --help Print help
-V, --version Print version
cargo run -- -V
MyApp 0.1.0
next_line_help
use clap::Parser; #[derive(Parser)] #[command(name = "MyApp")] #[command(version, about)] #[command(next_line_help = true)] struct Cli { #[arg(long)] two: String, #[arg(long)] one: String, } fn main() { let cli = Cli::parse(); println!("two: {:?}", cli.two); println!("one: {:?}", cli.one); }
执行程序查看结果,帮助信息会在下一行展示
$ cargo run -- --help
A simple CLI app using clap
Usage: clap_config_from_cargo --two <TWO> --one <ONE>
Options:
--two <TWO>
--one <ONE>
-h, --help
Print help
-V, --version
Print version
添加参数
位置参数
默认结构体字段会被定义为位置参数
use clap::Parser; #[derive(Parser)] #[command(name = "MyApp")] #[command(version, about)] #[command(next_line_help = true)] struct Cli { name: String, } fn main() { let cli = Cli::parse(); println!("name:{:?}", cli.name); }
执行命令查看输出
$ cargo run -- hzx
name:"hzx"
接收多个值
use clap::Parser; #[derive(Parser)] #[command(name = "MyApp")] #[command(version, about)] struct Cli { name: Vec<String>, } fn main() { let cli = Cli::parse(); println!("name:{:?}", cli.name); }
执行命令并查看,可以接收多个值
$ cargo run -- hzx hj
name:["hzx", "hj"]
选项
可以使用 #[arg(short='n')] 、#[arg(long=name)] 属性在一个字段上。当没有值提供时如 #[arg(short,long)] 将会使用字段名称。
use clap::Parser; struct Cli { #[arg(short, long)] name: String, } fn main() { let cli = Cli.parse(); println!("name: {:?}", cli.name); }
执行程序
$ cargo run -- --name bob
$ cargo run -- --name=bob
$ cargo run -- -n bob
$ cargo run -- -n=bob
$ cargo run -- -nbob
name: "bob"
接收多个值
use clap::Parser; #[derive(Parser)] #[command(version, about, long_about = None)] struct Cli { #[arg(short, long)] name: Vec<String>, } fn main() { let cli = Cli::parse(); println!("name: {:?}", cli.name); }
$ cargo run -- --name bob --name jam
name: ["bob", "jam"]
标志(Flags)
Flags 是一个开关,如果指定该参数就是开,不指定就是关
use clap::Parser; #[derive(Parser)] #[command(version, about, long_about = None)] struct Cli { #[arg(short, long)] verbose: bool, } fn main() { let cli = Cli::parse(); println!("verbose: {:?}", cli.verbose); }
执行程序并查看结果
$ cargo run -- -v
verbose: true
$ cargo run --
verbose: false
可选参数
use clap::Parser; #[derive(Parser)] #[command(version, about, long_about = None)] struct Cli { name: Option<String>, } fn main() { let cli = Cli::parse(); println!("name: {:?}", cli.name); }
$ cargo run
name: None
$ cargo run jam
name: Some("jam")
默认值
use clap::Parser; #[derive(Parser)] #[command(version, about, long_about = None)] struct Cli { #[arg(default_value_t = 2020)] port: u16, #[arg(default_value = "127.0.0.1")] host: String, } fn main() { let cli = Cli::parse(); println!("host: {:?}", cli.host); println!("port: {:?}", cli.port); }
$ cargo run
host: "127.0.0.1"
port: 2020
$ cargo run 22
host: "127.0.0.1"
port: 22