空き時間ができたので久しぶりにrustの勉強です。
文法など少し忘れているので以前に書いたコードをいじってみました。
コマンドラインのオプション処理に使用していたclapがバージョンアップと共に以前のコードでは動かなくなっていたので書き直してみました。
どうやらメジャーバージョンアップ毎に書き方が変化しているようです。rustのDeriveによりシンプルな書き方に変わっているのでしょう。
一応以前のBuilderタイプも使用できるようです。おそらく今後はサポートされない方向性だと思います。
Deriveタイプで書き直してみました。以前のclap v2よりすっきりしましたね。
Deriveを使うには、
$ cargo add clap --features derive
で、有効化して下記例のようにArgsを設定すればオプションを定義できます。
この例では、ショート形式オプションが-d、ロング形式が–dir、デフォルト値がカレントフォルダを表すドット( . )、スラッシュ3つのコメントがそのままコマンドの説明文として使用されます。
下記はコマンドヘルプの出力例です。
Usage: test_clapv4 [OPTIONS]
Options:
-d, --dir <DIR> target directory [default: ./]
-h, --help Print help
-V, --version Print version
use anyhow::Result; // 1.0.71
use clap::Parser; // 4.3.11
use std::fs;
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// target directory
#[arg(short, long, default_value_t = String::from("./") )]
dir: String,
}
fn main() -> Result<()> {
let args = Args::parse();
let dir_string = args.dir.to_string();
println!("{}", dir_string);
let _ = get_dirs(dir_string);
Ok(())
}
fn get_dirs(dir: String) -> Result<()> {
let mut entries = fs::read_dir(dir)?;
while let Some(entry) = entries.next() {
let entry = entry?;
let metadata = entry.metadata()?;
let path = entry.path();
if metadata.is_dir() {
let path = path.display().to_string();
println!("{}", path);
let _ = get_dirs(path);
continue;
}
if let Ok(symlink) = fs::read_link(&path) {
if path.is_dir() {
println!("{}@ -> {}", path.display(), symlink.display());
}
}
}
Ok(())
}