引き続き前回のネタの続きですが、JavaScriptのasync/awaitの記事が観覧数が多いのでrustでもasync/awaitを試してみたいと思います。
ファイル読み込み等していないのですがメタデータの読み込みはファイルIOの一種なのでtokioの方で用意されていました。
単純にasync/awaitのキーワードを入れていくだけでしたが動いています。あまり深く考えずにやったせいなのか前回バージョンより約60倍遅いです。
use anyhow::Result; // 1.0.71
use clap::Parser; // 4.3.11
use async_recursion::async_recursion; // 1.0.4
use tokio::fs; // 1.29.1
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
/// target directory
#[arg(short, long, default_value_t = String::from(".") )]
dir: String,
}
#[tokio::main]
async fn main() -> Result<()> {
let args = Args::parse();
let dir_string = args.dir.to_string();
println!("{}", dir_string);
let _ = get_dirs(dir_string).await?;
Ok(())
}
#[async_recursion]
async fn get_dirs(dir: String) -> Result<()> {
let mut entries = fs::read_dir(dir).await?;
while let Some(entry) = entries.next_entry().await? {
let metadata = entry.metadata().await?;
let path = entry.path();
if metadata.is_dir() {
let path = path.display().to_string();
println!("{}", path);
let _ = get_dirs(path).await?;
continue;
}
if let Ok(symlink) = fs::read_link(&path).await {
if path.is_dir() {
println!("{}@ -> {}", path.display(), symlink.display());
}
}
}
Ok(())
}