clap とは?
clap クレート は、コマンドライン引数のパーサーライブラリで、次のような機能を備えています。
- 一般的なオプション形式(
-a
や--name val
)や、サブコマンド形式の引数のパース - ヘルプ出力 (usage) の自動生成
- シェル用の入力補完スクリプト生成(clap_complete クレート)
derive
マクロにより多くのボイラプレートコードを自動生成してくれるので、コードをシンプルに保ちつつ、高度なコマンドライン引数処理を行うことができます。
clap を使う準備
clap
クレートを使うために、最初に Cargo.toml
に依存関係を追加しておきます。
derive
マクロを有効にするために、--features derive
オプションが必要です。
次のように依存関係が追加されていれば OK です。
clap の基本
任意の構造体定義に、clap
が提供する #[derive(Parser)]
マクロを付加することで、コマンドライン引数用のバッファとして使えるようになります。
上記のように定義した Args
構造体は、自動的に parse
メソッドを備えるようになり、これを main
関数で呼び出すことで、コマンドライン引数をパースしてフィールドに格納してくれます。
下記は、正しくコマンドライン引数を指定した場合の実行結果です。
上記の実行例は、myapp
という名前の実行ファイルを生成したと想定しています。
cargo
コマンドで直接実行する場合は、次のような感じでコマンドライン引数を指定します。
$ cargo -q run -- aaa 100
-q
オプションは Cargo
の冗長なメッセージを抑制するもので、--
はそれ以降のコマンドライン引数をプログラム側に渡すことを示しています。
構造体の first
フィールドに "aaa"
という文字列が格納され、second
フィールドに 100
という数値が格納されています。
second
フィールドは、u32
型として定義されているので、ユーザーが数値以外を入力すると、clap
はヘルプメッセージを出力してプログラムを終了 (Error#exit
) します。
メッセージの内容は clap
が自動生成してくれます。
これだけでも十分に便利ですが、clap
はさらに -h
や --help
オプションを自動で実装してくれます。
表示されるヘルプメッセージは、構造体のドキュメンテーションコメント (///
) の記述から自動生成されます。
Linux スタイルのコマンドライン引数
-f
や --foo
のような Linux スタイルのコマンドライン引数を定義するには、構造体のフィールドに #[arg(short, long)]
属性を付加します。
/// Simple program to greet a person
#[derive(Parser)]
struct Args {
/// Name of the person to greet
#[arg(short, long)]
name: String,
/// Number of times to greet
#[arg(short, long)]
count: u8,
/// Run in debug mode
#[arg(short, long)]
debug: bool,
}
デフォルトでは、構造体のフィールド名 (name
) から、-n
や --name
といったオプションが自動生成されます。
$ ./myapp --help
Simple program to greet a person
Usage: myapp --name <NAME> --count <COUNT>
Options:
-n, --name <NAME> Name of the person to greet
-c, --count <COUNT> Number of times to greet
-d, --debug Run in debug mode
-h, --help Print help information
他にも次のような属性指定が可能です。
#[arg(short)]
… 短い形式のオプション (-n
) のみ生成します。#[arg(long)]
… 長い形式のオプション (--name
) のみ生成します。#[arg(short = 'x')]
… 短い形式のオプション名を-x
に変更します。#[arg(long = "xyz")]
… 短い形式のオプション名を--xyz
に変更します。
省略可能なパラメーターとデフォルト値
構造体のフィールドの型を Option 列挙型 として定義すると、そのコマンドライン引数は省略可能になります。
ユーザーがコマンドライン引数を指定しなかった場合、対応するフィールドの値は Option::None
となります。
fn main() {
let args = Args::parse();
match &args.name {
Some(name) => println!("Hello, {}", name),
None => println!("Who are you?"),
}
}
bool
型のフィールドに関しては、Option
型にしなくても省略可能なフラグとして機能します。
ユーザーがこのフラグを指定しなかった場合は、デフォルト値として false
が格納されます。
次のように default_value
でデフォルト値を設定しておくこともできます。
この場合も、フィールドを Option
型にする必要はありません。
Linux 形式ではないコマンドライン引数 (positional arguments) も通常は必須のコマンドライン引数として扱われますが、Optional
型にするか、デフォルト値を指定することで、省略可能にすることができます。
特定の値だけ指定できるようにする (ValueEnum)
決められた値のいずれかのみを指定できるオプションを定義するには、ValueEnum
使って次のようにします。
ここでは、--format
オプションで json
、yaml
、toml
のいずれかを指定できるように実装しています。
ユーザーが --format
オプションを指定しなかった場合は、デフォルトで json
が使われます。
use clap::{Parser, ValueEnum};
#[derive(Parser)]
struct Args {
/// Output format
#[arg(short, long)]
#[clap(value_enum, default_value_t=Format::Json)]
format: Format,
}
#[derive(ValueEnum, Clone, Debug)]
enum Format {
Json,
Yaml,
Toml,
}
fn main() {
let args = Args::parse();
println!("format = {:?}", args.format);
}
ヘルプもそれっぽい内容で表示してくれます。
$ ./myapp --help
Usage: myapp [OPTIONS]
Options:
-f, --format <FORMAT> Output format [default: json] [possible values: json, yaml, toml]
-h, --help Print help information
ヘルプ表示のカスタマイズ
値のプレースホルダー名 (value_name)
値を持つパラメーターの場合、ヘルプ表示においてその値の部分は <フィールド名>
というプレースホルダで表示されますが、その表示は value_name
でカスタマイズできます。
上記のように指定すると、ヘルプ表示で --input <INPUT>
と表示されていた部分が、--input <PATH>
という表示に変わります。
詳細説明
アプリケーションや各パラメーターの詳細説明は次のように記述します。
この詳細説明を表示するには、--help
オプションを指定してプログラムを起動します(-h
では表示されません)。
$ ./myapp --help
My app
Long long long description. Long long long description. Long long long description.
Usage: myapp <NAME>
Arguments:
<NAME>
Your name
Long long long description. Long long long description. Long long long description.
Options:
-h, --help
Print help information (use `-h` for a summary)