clap教程:第2章

官方参考: https://docs.rs/clap/4.5.1/clap/_derive/_tutorial/chapter_2

附加参数

  1. Postitionals, 位置参数
  2. Options, 选项参数
  3. Flags, 标志参数
  4. Subcommands, 子命令
  5. Defaults, 默认值

位置参数

你可以让用户按其在命令行上的位置指定值:

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.as_deref());
}
$ 03_03_positional_derive --help
用法: 03_03_positional_derive[EXE] [名称]

参数:
  [名称]  

选项:
  -h, --help     打印帮助信息
  -V, --version  打印版本号

$ 03_03_positional_derive
name: None

$ 03_03_positional_derive bob
name: Some("bob")

需要注意默认的参数动作是设置(Set)。如果要接受多个值,则可以通过使用 Append 动作并通过 Vec 类型进行重写:

use clap::Parser;

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
    name: Vec<String>,
}

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

    println!("name: {:?}", cli.name);
}
$ 03_03_positional_mult_derive --help
用法: 03_03_positional_mult_derive[EXE] [名称]...

参数:
  [名称]...  

选项:
  -h, --help     打印帮助信息
  -V, --version  打印版本号

$ 03_03_positional_mult_derive
name: []

$ 03_03_positional_mult_derive bob
name: ["bob"]

$ 03_03_positional_mult_derive bob john
name: ["bob", "john"]

选项参数

你可以使用标志为参数命名:

  • 顺序不重要
  • 可选的
  • 意图清晰

要为参数指定标志,可以在字段上使用 #[arg(short = 'n')] 和(或) #[arg(long = "name")] 属性。当没有给出值时(例如 #[arg(short)]),标志将从字段的名称推断。

use clap::Parser;

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
    #[arg(short, long)]
    name: Option<String>,
}

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

    println!("name: {:?}", cli.name.as_deref());
}
$ 03_02_option_derive --help
用法: 03_02_option_derive[EXE] [选项]

选项:
  -n, --name <名称>  
  -h, --help         打印帮助信息
  -V, --version      打印版本号

$ 03_02_option_derive
name: None

$ 03_02_option_derive --name bob
name: Some("bob")

$ 03_02_option_derive --name=bob
name: Some("bob")

$ 03_02_option_derive -n bob
name: Some("bob")

$ 03_02_option_derive -n=bob
name: Some("bob")

$ 03_02_option_derive -nbob
name: Some("bob")

需要注意默认的参数动作是设置(Set)。如果要接受多个值,则可以通过使用 Append 动作并通过 Vec 类型进行重写:

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);
}
$ 03_02_option_mult_derive --help
用法: 03_02_option_mult_derive[EXE] [选项]

选项:
  -n, --name <名称>  
  -h, --help         打印帮助信息
  -V, --version      打印版本号

$ 03_02_option_mult_derive
name: []

$ 03_02_option_mult_derive --name bob
name: ["bob"]

$ 03_02_option_mult_derive --name=bob
name: ["bob"]

$ 03_02_option_mult_derive -n bob
name: ["bob"]

$ 03_02_option_mult_derive -n=bob
name: ["bob"]

$ 03_02_option_mult_derive -nbob
name: ["bob"]

标志参数

标志参数也可以是开关,可以是开或关:

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);
}
$ 03_01_flag_bool_derive --help
用法: 03_01_flag_bool_derive[EXE] [选项]

选项:
  -v, --verbose  
  -h, --help     打印帮助信息
  -V, --version  打印版本号

$ 03_01_flag_bool_derive
verbose: false

$ 03_01_flag_bool_derive --verbose
verbose: true

$ 03_01_flag_bool_derive --verbose --verbose
? 失败
错误:参数 '--verbose' 不能多次使用

用法: 03_01_flag_bool_derive[EXE] [选项]

获取更多信息,请尝试 '--help'

请注意,默认的 ArgAction 对于 bool 字段是 SetTrue。要

接受多个标志,请通过 Count 来重写 action 属性:

use clap::Parser;

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
    #[arg(short, long, action = clap::ArgAction::Count)]
    verbose: u8,
}

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

    println!("verbose: {:?}", cli.verbose);
}
$ 03_01_flag_count_derive --help
用法: 03_01_flag_count_derive[EXE] [选项]

选项:
  -v, --verbose...  
  -h, --help        打印帮助信息
  -V, --version     打印版本号

$ 03_01_flag_count_derive
verbose: 0

$ 03_01_flag_count_derive --verbose
verbose: 1

$ 03_01_flag_count_derive --verbose --verbose
verbose: 2

这还表明任何 Arg 方法都可以用作属性。

子命令

子命令使用 #[derive(Subcommand)] 派生,通过在使用该类型的字段上使用 #[command(subcommand)] 属性添加。每个 Subcommand 实例都可以有自己的版本、作者、参数,甚至可以有自己的子命令。

use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command(version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// 添加文件到 myapp
    Add { name: Option<String> },
}

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

    // 你可以检查是否存在子命令,并在找到时使用它们的匹配,就像处理顶级命令一样
    match &cli.command {
        Commands::Add { name } => {
            println!("'myapp add' 被使用,名称是: {name:?}")
        }
    }
}

我们使用了结构体变体来定义 add 子命令。或者,你也可以使用结构体来定义子命令的参数:

use clap::{Args, Parser, Subcommand};

#[derive(Parser)]
#[command(version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// 添加文件到 myapp
    Add(AddArgs),
}

#[derive(Args)]
struct AddArgs {
    name: Option<String>,
}

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

    // 你可以检查是否存在子命令,并在找到时使用它们的匹配,就像处理顶级命令一样
    match &cli.command {
        Commands::Add(name) => {
            println!("'myapp add' 被使用,名称是: {:?}", name.name)
        }
    }
}
$ 03_04_subcommands_derive help
用法: 03_04_subcommands_derive[EXE] <命令>

命令:
  add   添加文件到 myapp
  help  打印此消息或给定子命令的帮助信息

选项:
  -h, --help     打印帮助信息
  -V, --version  打印版本号

$ 03_04_subcommands_derive help add
添加文件到 myapp

用法: 03_04_subcommands_derive[EXE] add [名称]

参数:
  [名称]  

选项:
  -h, --help     打印帮助信息
  -V, --version  打印版本号

$ 03_04_subcommands_derive add bob
'myapp add' 被使用,名称是: Some("bob")

当指定命令时,它们是必需的。或者,你可以使用 command: Option<Commands> 来使其可选。

$ 03_04_subcommands_derive
? 失败
用法: 03_04_subcommands_derive[EXE] <命令>

命令:
  add   添加文件到 myapp
  help  打印此消息或给定子命令的帮助信息

选项:
  -h, --help     打印帮助信息
  -V, --version  打印版本号

由于我们指定了 #[command(propagate_version = true)],因此 --version 标志在所有子命令中都可用:

$ 03_04_subcommands_derive --version
clap [..]

$ 03_04_subcommands_derive add --version
clap-add [..]

默认值

我们之前展示了参数可以是 required 或可选的。当可选时,你可以使用 Option 并且可以 unwrap_or。或者,你可以设置 #[arg(default_value_t)]

use clap::Parser;

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli

 {
    #[arg(default_value_t = 2020)]
    port: u16,
}

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

    println!("port: {:?}", cli.port);
}
$ 03_05_default_values_derive --help
用法: 03_05_default_values_derive[EXE] [端口]

参数:
  [端口]  [默认值: 2020]

选项:
  -h, --help     打印帮助信息
  -V, --version  打印版本号

$ 03_05_default_values_derive
port: 2020

$ 03_05_default_values_derive 22
port: 22

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值