以下の内容はhttps://nikkie-ftnext.hatenablog.com/entry/rust-clap-beginner-steps-option-args-and-subcommandsより取得しました。


あの日argparseで書いたプログラムのRust版を僕はまだ知らない。第2話 ゆうしゃオプション・第3話 サブコマンドを探そうの会

はじめに

とぅーす!」(かわいい) nikkieです。

Pythonのargparseで書いたCLIをRustのCLAPで再実装してみようシリーズ(※小さな素振り群)の続編、2話連続放送です!
第1話はこちら

CLAPの素振り その1:オプション引数

今手元にあるのは位置引数で指定するバージョン

$ cargo run --quiet シオン 3
シオンシオンシオン
#[derive(Parser)]
struct Cli {
    string: String,
    #[clap(default_value = "3")]
    number: usize,
}

これをオプション引数で渡せるように変更します。

$ cargo run --quiet -- -s シオン -n 3
シオンシオンシオン

そのやり方はExampleにありました。
https://docs.rs/clap/latest/clap/#example
[#[arg(short, long)]]1

#[derive(Parser)]
struct Cli {
    #[arg(short)]
    string: String,
    #[arg(short, default_value = "3")]
    number: usize,
}

[#[arg(short, long)]]との違いの1つはヘルプメッセージです(longを指定してよいと思います)

Options:
  -s <STRING>      
  -n <NUMBER>      [default: 3]
Options:
  -s, --string <STRING>  
  -n, --number <NUMBER>  [default: 3]

CLAPの素振り その2:サブコマンド

参考:Pythonのargparseの例はこちら

位置引数サブコマンドとオプション引数サブコマンドを実装してみます。

$ cargo run --quiet -- position 天才 5
天才天才天才天才天才
$ cargo run --quiet -- option -s おはぎ -n 2
おはぎおはぎ

参考にしたのは、cookbookのgitの例。

use clap::{Parser, Subcommand};

#[derive(Parser)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    Position {
        string: String,
        #[arg(default_value = "3")]
        number: usize,
    },
    Option {
        #[arg(short, long)]
        string: String,
        #[arg(short, long, default_value = "3")]
        number: usize,
    },
}

コマンド自体の実装はこのように続きます

fn main() {
    let args = Cli::parse();
    match args.command {
        Commands::Position { string, number } => {
            println!("{}", string.repeat(number));
        }
        Commands::Option { string, number } => {
            println!("{}", string.repeat(number));
        }
    }
}

enumのコマンドに応じてパターンマッチ!
enumだから、args.commandCommands::PositionまたはCommands::Optionなわけですね。
サブコマンドまでできちゃった!

終わりに

RustのCLAPで

  • オプション引数も持つCLIが作れました!
    • [#arg(short, long)]
  • サブコマンドも実装できました!
    • enumを定義し、#[derive(Parser)]の付いたStructでそのenumを指定する

ここまでの3話で、argparseで書いているCLIの8割くらいは、RustのCLAPでも今の私は書けるのではという感触です(※まさに馬鹿の山です)。
コマンドライン引数のパーサはどう書けばいいか分かってきたので、内部の処理に移ったらアイデアCLIという形にできて楽しそうです。

今回のソースコードはこちらです(引き続きテストもあります!)


  1. デフォルト値は#[clap(default_value = "3")]としていました。#[clap(...)]#[arg(...)]は交換可能に思われます(さらに詳しくは宿題事項)



以上の内容はhttps://nikkie-ftnext.hatenablog.com/entry/rust-clap-beginner-steps-option-args-and-subcommandsより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14