use std::error::Error;
use std::io;
use std::path::Path;
use smol::fs::read_dir;
use smol::stream::StreamExt;
use vuot::{run, Stack, StacklessFn};
smol_macros::main! {
async fn main() -> Result<(), Box<dyn Error>> {
let current_dir = std::env::current_dir()?;
run(Traversal(¤t_dir)).await?;
Ok(())
}
}
struct Traversal<'local>(&'local Path);
impl<'a> StacklessFn<'a, Result<(), io::Error>> for Traversal<'_> {
async fn call(self, stack: Stack<'a>) -> Result<(), io::Error> {
traverse(stack, 0, self.0).await
}
}
async fn traverse(stack: Stack<'_>, nesting: usize, dir: &Path) -> Result<(), io::Error> {
let mut entries = read_dir(dir).await?;
while let Some(entry) = entries.next().await {
let entry = entry?;
let name = entry.file_name();
let name = name.to_string_lossy();
let file_type = entry.metadata().await?.file_type();
if file_type.is_dir() {
indented(nesting, format!("directory {name}"));
let path = entry.path();
stack.run(traverse(stack, nesting + 1, &path)).await?;
} else {
indented(nesting, format!("file {name}"));
}
}
Ok(())
}
fn indented(n: usize, s: String) {
for _ in 0..n {
print!("| ");
}
println!("{s}");
}