clap v3 のdriveベースのパースのサンプル
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, }, }