clap
最近在学习Rust, 有用到命令行参数解析库clap , 在此记录一下
对于简单的参数完全可以手动处理无需引入额外的依赖, 但当命令和参数比较多的时候可以就可以使用第三方库来简化开发
clap
clap提供两种模式, builder模式和derive模式, 具体使用哪种方式全凭个人喜好derive模式通过宏自动生成代码, 将参数映射到struct或者enum中, 结构清晰, 但需要查阅文档记一下参数 builder模式支持动态参数, 运行时配置和一些复杂的校验逻辑, 可以按需构建解析器, 但需要手动维护参数和子命令的层次结构 clap会自动生成帮助文档 derive模式
安装: cargo add clap --features derive
位置参数
x <属性值1> <属性值2>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use clap ::Parser ;
#[derive(Parser)] // 必须添加Parser派生宏
struct Study {
// 这里没有任何自定义属性宏, 使用时就是位置参数
a : u8 ,
b : u8 ,
}
fn main () {
let cli = Study ::parse ();
println! ( "a: {:?} " , cli . a );
println! ( "b: {:?} " , cli . b );
}
// cargo run -- --help
// cargo run -- 3 4
// cargo run -- 100 1
命名参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use clap ::Parser ;
#[derive(Parser)] //必须写
struct Study {
#[arg(short)] //short表示使用单横杠方式(默认是首字母): -n <name值> 或者 -n=<name值>
// #[arg(short='N')] short默认取首字母, 可能会和其他的冲突, 所以可以手动指定一个字母
#[arg(long)] //short表示使用双横杠方式: --name <name值> 或者 --name=<name值>
name : String ,
}
fn main () {
let cli = Study ::parse ();
println! ( "name: {:?} " , cli . name );
}
// cargo run -- --help
// cargo run -- -n jack
// cargo run -- --name=jack
属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
use clap ::Parser ;
#[command(name= "cli" )] // 输出version的时候一并输出
#[derive(Parser)] //必须写
#[command(version= "0.1.0" ,about= "intro attribute" )] // 指定version和about
struct Study {
#[arg(default_value= "default_name" )] // 指定默认值
name : String ,
}
fn main () {
let cli = Study ::parse ();
println! ( " {} " , cli . name );
}
// cargo run -- --help
// 下面是默认的help
introduce attribute
Usage : demo . exe [ NAME ]
Arguments :
[ NAME ] [ default : default_name ]
Options :
- h , -- help Print help
- V , -- version Print version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use clap ::Parser ;
#[derive(Parser)]
#[command(version= "0.1.0" ,about= "introduce attribute" )]
#[command(next_line_help = true)]
struct Study {
#[arg(long)]
name : String ,
}
fn main () {
let cli = Study ::parse ();
println! ( " {} " , cli . name );
}
// cargo run -- --help
// demo --help
// 观察下方输出, 'Print help'和'Print version'换行输出显示的
// 上面的例子中是没有换行显示输出的
introduce attribute
Usage : demo . exe -- name < NAME >
Options :
-- name < NAME >
- h , -- help
Print help
- V , -- version
Print version
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
use clap ::Parser ;
#[derive(Parser)] //必须写
struct Study {
#[arg(long)]
#[arg(help = "help about name" )]
name : String ,
}
fn main () {
let cli = Study ::parse ();
println! ( " {} " , cli . name );
}
// cargo run -- --help
// demo --help
Usage : demo . exe -- name < NAME >
Options :
-- name < NAME > help about name
- h , -- help Print help
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
use clap ::Parser ;
#[derive(Parser)]
struct Study {
#[arg(long)]
/// help about name by doc
name : String ,
}
fn main () {
let cli = Study ::parse ();
println! ( " {} " , cli . name );
}
// cargo run -- --help
// demo --help
Usage : demo . exe -- name < NAME >
Options :
-- name < NAME > help about name by doc
- h , -- help Print help
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
use clap ::Parser ;
#[derive(Parser)]
struct Study {
#[arg(long)]
#[arg(
help = "help about name" ,
value_name = "名字"
)]
name : String ,
}
fn main () {
let cli = Study ::parse ();
println! ( " {} " , cli . name );
}
// cargo run -- --help
// demo --help
Usage : demo . exe -- name < 名字 >
Options :
-- name < 名字 > help about name
- h , -- help Print help
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
use clap ::Parser ;
#[derive(Parser)]
struct Study {
#[arg(long)]
name : Option < String > ,
}
fn main () {
let cli = Study ::parse ();
println! ( " {:?} " , cli . name );
}
// cargo run -- --help
// demo --help
// 可以看到name是可选参数
Usage : demo . exe [ OPTIONS ]
Options :
-- name < NAME >
- h , -- help Print help
子命令
在clap中声明子命令可以使用以下方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use clap ::Subcommand ;
use clap ::Parser ;
#[derive(Parser, Debug)]
struct Cli {
#[command(subcommand)] //表示command是一个子命令, 类型是一个enum类型
command : Command ,
}
#[derive(Subcommand, Debug)]
enum Command {
/// Get request
Get {
#[arg(help = "URL to fetch" )]
#[arg(long)]
url : String ,
},
}
fn main () {
let _ = Cli ::parse ();
}
// 默认不显示子命令的参数信息
// cargo run -- --help
// cargo run -- help
// demo --help
// demo help
Usage : demo . exe < COMMAND >
Commands :
get Get request
help Print this message or the help of the given subcommand ( s )
Options :
- h , -- help Print help
// 查看子命令的帮助信息
// cargo run -- help get
// demo help get
Get request
Usage : demo . exe get -- url < URL >
Options :
-- url < URL > URL to fetch
- h , -- help Print help