RustでCLIツールを作成する方法|structopt入門

先生

RustでCLIツールを作るならstructopt! 爆速でコマンドライン引数を処理して、開発を楽に進めよう🚀

Rust CLIツール開発入門:structoptで楽々実装

RustでCLI(コマンドラインインターフェース)ツールを作りたいと思ったことはありませんか? Rustの強力な型システムとパフォーマンスは、CLIツール開発にも最適です。しかし、コマンドライン引数のパースは少し面倒な作業になりがちです。そこで登場するのが structopt です。

structopt は、構造体の定義からコマンドライン引数のパーサーを自動生成してくれるクレートです。これにより、ボイラープレートコードを大幅に削減し、ビジネスロジックに集中できます。この記事では、structopt を使って簡単なCLIツールを作成する手順を解説します。

この記事を読むことで、RustでのCLIツール開発の敷居を下げ、より効率的に開発を進めることができるようになるでしょう。

structoptのインストールと設定

まず、structopt をプロジェクトに追加します。Cargo.toml ファイルに以下の依存関係を追加してください。


toml
[dependencies]
structopt = "0.3"

次に、src/main.rsstructopt をインポートし、deriveマクロを使用できるようにします。


rust
use structopt::StructOpt;

#[derive(StructOpt)]
struct Cli {
    // コマンドライン引数の定義
}

fn main() {
    // コマンドライン引数の解析
}

簡単なCLIツールの作成例

ここでは、指定されたファイルの内容を表示する簡単なCLIツールを作成します。Cli 構造体は、ファイルパスを受け取るように定義します。


rust
use structopt::StructOpt;
use std::path::PathBuf;

#[derive(StructOpt)]
#[structopt(name = "cat", about = "A simple cat command implemented in Rust.")]
struct Cli {
    /// The file to read
    #[structopt(parse(from_os_str), short, long)]
    path: PathBuf,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args = Cli::from_args();
    let contents = std::fs::read_to_string(args.path)?;
    println!("{}", contents);
    Ok(())
}

このコードでは、path フィールドにファイルパスを指定します。#[structopt(parse(from_os_str))] は、OSに依存しないパス形式でファイルパスを解析するためのアトリビュートです。shortlong は、それぞれ短いオプション名と長いオプション名を定義します。

ビルドして実行するには、cargo build コマンドを実行し、その後、以下のように実行します。


bash
./target/debug/cat --path input.txt

input.txt の内容が表示されます。

structoptの応用:サブコマンドの追加

structopt を使うと、サブコマンドも簡単に実装できます。例えば、addremove という2つのサブコマンドを持つCLIツールを作成する場合、以下のように構造体を定義します。


rust
use structopt::StructOpt;

#[derive(StructOpt)]
#[structopt(name = "myapp")]
struct Cli {
    #[structopt(subcommand)]
    cmd: Commands,
}

#[derive(StructOpt)]
enum Commands {
    Add { name: String },
    Remove { id: u32 },
}

fn main() {
    let args = Cli::from_args();

    match args.cmd {
        Commands::Add { name } => {
            println!("Adding {}", name);
        }
        Commands::Remove { id } => {
            println!("Removing {}", id);
        }
    }
}

この例では、Commands というenumを定義し、Cli 構造体の cmd フィールドに #[structopt(subcommand)] アトリビュートを追加しています。これにより、add コマンドと remove コマンドを myapp コマンドのサブコマンドとして使用できます。


bash
./target/debug/myapp add --name "task1"
./target/debug/myapp remove --id 123

参考リンク

まとめ

structopt を使うことで、RustでのCLIツール開発が非常に簡単になります。この記事では、基本的な使い方からサブコマンドの実装までを解説しました。structopt は、コマンドライン引数のパースに関する多くのボイラープレートコードを自動生成してくれるため、開発者はビジネスロジックに集中できます。ぜひ、structopt を活用して、効率的なCLIツール開発を楽しんでください。