use log::warn; use std::io::Result; use tokio::fs; pub async fn walk_dir(dir: &str) -> Vec { let mut todo = Vec::new(); if let Ok(rd) = read_dir(dir).await { todo.push(rd); } let mut results = Vec::new(); while let Some(rd) = todo.pop() { for (path, is_dir) in rd { if is_dir { let Ok(child_rd) = (read_dir(&path).await) .inspect_err(|e| warn!("reading dir {path} failed: {e}")) else { continue; }; todo.push(child_rd); } else { results.push(path); } } } results } async fn read_dir(dir: &str) -> Result> { let mut rd = fs::read_dir(dir).await?; let mut entries = Vec::new(); while let Some(entry) = rd.next_entry().await? { if let Some(path) = entry.path().to_str() { entries.push((path.to_string(), entry.file_type().await?.is_dir())); } } entries.sort(); // we want a deterministic & intuitive order Ok(entries) }