getopts - Rust
起動時引数の解析用crate。公式が提供している。
Pythonのargparseと同じような使用感。
主にOptionsとMatchesの2つのオブジェクトが提供される。
Optionsオブジェクトにパースしたいキーワードとその解析方法を次々設定して、最後に Options.parse() で解析する。
返値のオブジェクトであるMatchesから、必要な情報を取得する。
単純な機能は過不足ない。「2つの内いずれかは必須」など複雑なことは出来ない。
解析できる構文
位置引数、キーワード引数、フラグ引数に対応(この名称は勝手に付けた)。キーワード引数とフラグ引数は、まとめて「オプション引数」と呼ばれることが多いかも。オプション引数の名前(ハイフンに続く文字)は自由に、「ハイフン1つ+1文字」の省略形と「ハイフン2つ+任意の文字数」のロング名とを設定できる。
> command AAA BBB -s CCC --longname DDD -e --flag AAA BBB が位置引数 -s CCC --longname DDD がキーワード引数(値を伴うオプション引数) -e --flag がフラグ引数(値を伴わないオプション引数)
位置引数
- 何番目の引数かによって指定
- キーワード引数とフラグ引数以外の引数を先頭から順に取得
- 「最初の位置引数が現れたら、後はハイフン付いていようと全て位置引数」と解釈するオプションが存在
キーワード引数
ハイフンから始まる所定のキーワードに続けて指定。
○: -o XXX or -oXXX or --opt XXX ×: -o=XXX or --opt=XXX
可変長引数は未対応だが、同じキーワードで複数回指定されたのを配列として受け取ることはできる。
×: -o XXX YYY ZZZ ○: -o XXX -o YYY -o ZZZ
- 「-aと-bを同時に指定することは出来ない」「-aを指定したら-bも指定しないといけない」などは未対応
- 指定されなかった場合のデフォルト値を指定可能
- FromStrtraitを実装している型なら、パースして返すよう指定することが可能
フラグ引数
-f –flag など単独でフラグとして指定。booleanで取得。
その他の機能
- ヘルプ用文字列の自動生成可
もっと複雑な構文が必要なら
Sample
extern crate getopts;
use getopts::Options;
use std::process;
// 引数を格納する構造体
#[derive(Debug)]
pub struct Args {
    repeat: usize,
    input: Vec<String>,
    output: String,
}
fn print_usage(exe_name: &str, opts: &Options) {
    let brief = format!("Usage: {} REPEAT [Options]", exe_name);
    print!("{}", opts.usage(&brief));
    process::exit(0);
}
pub fn parameters() -> Args {
    // コマンドラインオプションを取得
    let args: Vec<String> = std::env::args().collect();
    // キーワード引数を指定
    let mut opts = Options::new();
    opts.optmulti("i", "", "set input file names", "NAME");
    opts.optopt("o", "", "set output file name", "NAME");
    opts.optflag("h", "help", "print this help");
    // パース
    let matches = opts.parse(&args[1..])
        .unwrap_or_else(|f| panic!(f.to_string()));
    // "h" が存在したらヘルプを表示して終了
    if matches.opt_present("h") {
        print_usage(&args[0], &opts);
    }
    // 必要な位置引数がなかったらヘルプを表示して終了
    if matches.free.is_empty() {
        print_usage(&args[0], &opts);
    }
    // キーワード引数の取得
    let input = matches.opt_strs("i");
    let output = matches.opt_str("o").unwrap_or("Default Value".to_string());
    // 位置引数の取得
    let repeat = matches.free[0].clone().parse::<usize>()
        .unwrap_or_else(|f| panic!(f.to_string()));
    // 構造体の生成
    let ret = Args {
        repeat,
        input,
        output,
    };
    return ret;
}
fn main() {
    let args = parameters();
    println!("{:?}", args);
}





