Open11
RustでCLIツールを作ってみた
RustでCLIツールを作ろう!
なぜ僕は作ろうとしているのか
研究で「作った方が作業が楽だな」と感じたため
作るものの内容を決めよう!
今回作るもの
- WebAssemblyモジュール開発時に役立つCLI
- 開発プロジェクトの作成
- Rust,Go
- Rustは
wasm-pack
- Goは
TinyGo
- Rustは
- Rust,Go
- 開発プロジェクト内のプログラムをコンパイル
- コンパイルして生成されたファイルは指定したフォルダに格納
- 開発プロジェクトの作成
どういうコマンドを打てば動くようにするか
help
- どういうコマンドを打ったらどの機能が使えるかを表示する
create
- プロジェクトの作成
- 引数
- 言語名(rust,go)
- プロジェクト名
- 実行すると、指定した言語でWebAssemblyモジュールを開発するディレクトリやファイルを作成
- 引数
build
- プロジェクト内のプログラムをビルド(コンパイル)する
- 引数
- コンパイルして生まれるファイルの名前
- 未指定だとプロジェクト名がついたファイルとしてコンパイル
- 出力されるファイルを格納するフォルダ名
- コードが入っているディレクトリと同じ階層に作成されるフォルダの名前を決める
- コンパイルして生まれるファイルの名前
- 引数
今回参照するURL
まず入力された文字をParseしよう!
clap
でParseする
コマンドライン引数をParseするためのライブラリとして
clap(Command Line Agrument Parser)
を使用します。
cargo add clap@4.4.11 --features derive
まずこんなコード書く
main.rs
+ use clap::Parser;
+ #[derive(Parser)]
+ type ○○ struct {
+ フィールド 型;
+ ・・・
+ }
fn main(){
+ let args = ○○::parse();
}
なんとこの時点でhelpコマンドが自動的に登録される
便利~!!✨
また、Cargo.toml
の内容に合わせて
[package]
name = "example"
version = "1.0.0"
edition = "2021"
+ description = "example project"
・・・
main.rs
use clap::Parser;
#[derive(Parser)]
+ #[command(version,about)]
type ○○ struct {
フィールド 型;
・・・
}
fn main(){
let args = ○○::parse();
}
こうすると、versionコマンドとCLIの説明文が出てくるようになる
引数の設定について
struct
で構造型を作成し、そのフィールドの上に以下のものを与えた時の挙動の対応は以下の通り
-
Vec<~~>
:複数の同じ型の値を許容 -
#[arg(short)]
: 省略系を許容- 例えば、プロパティ名が
f
で始まるなら、そのプロパティ名か-f
を許容する
- 例えば、プロパティ名が
-
#[arg(default_value_t = ○○)]
- デフォルト値を設定している
-
#[arg(short,long="lines")]
とOption<○○>
- Option型の引数で、長めのコマンド名を
lines
とする
- Option型の引数で、長めのコマンド名を
バリデート設定
バリデーションはいったんスキップします。ここを確認してください
インタラクティブ性を実現する
dialoguer
を使って入力を受け取る
- Select:選択肢を提示して選択してもらうパターン
- Input:標準入力の受けとり
実行時の進捗を確認!
indicatif
でプログレスバーを出す!
今回は扱わないので、リンク先参照
カラフルなログを出す!
console
でANSIエスケープをコードベースで可能にする!
これによって、
- ターミナル内のカーソル移動(文字列の削除・上書き)
- 色付き文字出力
- 絵文字サポート
- Unicode文字幅を考慮したPadding
Cargo.toml
に必要な依存パッケージを書いておきたい!
serde
&toml
でシリアライズ/デシリアライズして書き込みをする!
これを使って、書いておくべき内容を構造体として指定し、
create
実行時に生成されたtomlの内容に追記する形式で情報を追加していく!