Rustの定番コマンドラインパーサー clap が2022-01-01にバージョン3になり、deriveベースのコマンドラインのパースが正式実装された。
この機能は、従来は structopt が提供していた構造体を用いたコマンドライン引数の定義や、列挙型を用いたサブコマンドの定義を行う機能である。
この記事では、この derive ベースのパースのうち、よく使うであろうものを紹介する。
なお、すべての機能については clapのGitHub上のリポジトリにあるexamples を参照してほしい。
Cargo.toml での指定
今回のサンプルコードを実行するには、Cargo.tomlに以下の指定が必要である。
[dependencies]
clap = {version = "3.0.7", features = ["derive", "env"]}
コマンドライン引数の定義
まずは、コマンドライン引数の指定のパターンをサンプルコードで示す。
use std::path::PathBuf; use clap::{ArgEnum, Parser}; fn main() { let args = Args::parse(); println!("{:#?}", args); } #[derive(Debug, Parser)] #[clap(name = "struct", author, about, version)] struct Args { /// boolフラグ。 /// /// `short` を指定すると、 自動で変数名の頭文字を使用する。 /// `long` を指定すると、 自動で変数名を使用する。 /// /// `help` を指定していないため、 短いヘルプ(`-h`のとき) はこのコメントの冒頭が表示される。 /// `long_help` を指定していないため、 長いヘルプ(`--help`のとき) はこのコメントの全体が表示される。 #[clap(short, long)] bool_flag: bool, /// 整数を引数に取る必須フラグ。 /// /// 整数型を直接指定しているため、このフラグは必須である。 #[clap(short, long)] count: u64, /// 整数を引数に取るフラグ。 /// /// デフォルト値が指定されているため、コマンドラインでは省略可能である。 #[clap(short, long, default_value = "1")] default_value: u64, /// 文字列を引数に取るオプションのフラグ。 /// /// `Option<T>` を指定すると、このフラグを指定しない事が可能。 /// /// `help = "..."` でヘルプテキストを明に指定する。 #[clap(short, long, help = "オプションのテキスト")] text: Option<String>, /// 複数指定可能なフラグ。 #[clap(short, long)] multiple: Vec<String>, /// 複数指定可能なフラグのOption版。 /// /// こちらは、指定が0個の場合は `None` になる。 #[clap(short, long)] optional_multiple: Option<Vec<String>>, /// 出現回数を数えるタイプのフラグ。 /// /// verbosity の `-vvvv` のような指定で多用される。 #[clap(short, parse(from_occurrences))] verbose: usize, /// フラグの文字列を明に指定しているフラグ。 /// /// `default_value = ".."` でデフォルト値を指定できる。 #[clap(short = 'x', long = "xxx", default_value = "2")] renamed: u64, /// 列挙型のフラグ。 /// /// [`ArgEnum`] 経由でのパースの場合は、 `arg_enum` を指定する。 #[clap(short = 'M', arg_enum)] mode: Mode, /// 環境変数を読むフラグ。 /// /// `env` feature を有効にする必要がある。 #[clap(short, long, env)] username: Option<String>, /// 必須の位置引数。 arg1: String, /// オプションの位置引数。 /// /// この引数はオプションなので省略できる。 arg2: Option<PathBuf>, } /// モード指定用の列挙型。 /// /// [`ArgEnum`] でコマンドラインオプション用の列挙型にできる。 #[derive(Debug, Clone, ArgEnum)] enum Mode { Single, Multi, }
> struct.exe -h
struct 1.0.0
Igaguri <igagurimk@gmail.com>
clap v3 のサンプルプログラム集
USAGE:
struct.exe [OPTIONS] --count <COUNT> -M <MODE> <ARG1> [ARG2]
ARGS:
<ARG1> 必須の位置引数。
<ARG2> オプションの位置引数。
OPTIONS:
-b, --bool-flag
boolフラグ。
-c, --count <COUNT>
整数を引数に取る必須フラグ。
-d, --default-value <DEFAULT_VALUE>
整数を引数に取るフラグ。 [default: 1]
-h, --help
Print help information
-m, --multiple <MULTIPLE>
複数指定可能なフラグ。
-M <MODE>
列挙型のフラグ。 [possible values: single, multi]
-o, --optional-multiple <OPTIONAL_MULTIPLE>
複数指定可能なフラグのOption版。
-t, --text <TEXT>
オプションのテキスト
-u, --username <USERNAME>
環境変数を読むフラグ。 [env: USERNAME=kawasaki]
-v
出現回数を数えるタイプのフラグ。
-V, --version
Print version information
-x, --xxx <RENAMED>
フラグの文字列を明に指定しているフラグ。 [default: 2]
> struct.exe
error: The following required arguments were not provided:
--count <COUNT>
-M <MODE>
<ARG1>
USAGE:
struct.exe --count <COUNT> -M <MODE> --username <USERNAME> <ARG1>
For more information try --help
> struct.exe --count 42 -M single -m a -m 2 -m 6 foo
Args {
bool_flag: false,
count: 42,
default_value: 1,
text: None,
multiple: [
"a",
"2",
"6",
],
optional_multiple: None,
verbose: 0,
renamed: 2,
mode: Single,
username: Some(
"kawasaki",
),
arg1: "foo",
arg2: None,
}
サブコマンドの実装
clap v3 では、列挙型を用いたサブコマンド実装をサポートしている。
use clap::{Parser, Subcommand}; fn main() { let args = Args::parse(); println!("{:#?}", args); } /// サブコマンドを持つコマンドライン引数の構造体。 #[derive(Debug, Parser)] #[clap(name = "subcommand", author, about, version)] struct Args { #[clap(subcommand)] command: Commands, } /// サブコマンドの定義 #[derive(Debug, Subcommand)] enum Commands { /// コマンドライン引数をその場で指定しているサブコマンド。 Add { x: i64, y: i64 }, /// 指定を別構造体に切り出したサブコマンド。 /// /// 実際には中の構造体を別モジュールで定義する際などに有用。 Complex(Complex), } #[derive(Debug, clap::Args)] struct Complex { u: u64, v: u64, x: u64, y: u64, }
> subcommand.exe help
subcommand 1.0.0
Igaguri <igagurimk@gmail.com>
clap v3 のサンプルプログラム集
USAGE:
subcommand.exe <SUBCOMMAND>
OPTIONS:
-h, --help Print help information
-V, --version Print version information
SUBCOMMANDS:
add コマンドライン引数をその場で指定しているサブコマンド。
complex 指定を別構造体に切り出したサブコマンド。
help Print this message or the help of the given subcommand(s)
> subcommand.exe help add
subcommand.exe-add
コマンドライン引数をその場で指定しているサブコマンド。
USAGE:
subcommand.exe add <X> <Y>
ARGS:
<X>
<Y>
OPTIONS:
-h, --help Print help informatio
> subcommand.exe add 1 2
Args {
command: Add {
x: 1,
y: 2,
},
}