szopqa
1
Hello,
I wanted to dive more into tokio and async programming in rust and tried to implement directory crawler using tokio's fs. Here is the code:
use std::{fs, io};
use std::fs::*;
use std::path::Path;
use std::future::Future;
async fn visit_dirs(dir: &Path) -> io::Result<()> {
if dir.is_dir() {
let mut entries = tokio::fs::read_dir(dir).await?;
while let Some(entry) = entries.next_entry().await? {
let path = entry.path();
if path.is_dir() {
visit_dirs(&path).await?;
// tokio::spawn(visit_dirs(&path));
}
}
}
Ok(())
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
visit_dirs(Path::new(".")).await?;
Ok(())
}
The problem is that mentioned code gives me following error:
error[E0733]: recursion in an `async fn` requires boxing
--> src/main.rs:22:36
|
22 | async fn visit_dirs(dir: &Path) -> io::Result<()> {
| ^^^^^^^^^^^^^^ recursive `async fn`
|
Could tou please help me? How should I implement async recursion in rust?
Thanks
naim
2
Boxing the future will allow recursion:
use std::fs::*;
use std::future::Future;
use std::path::Path;
use std::pin::Pin;
use std::{fs, io};
fn visit_dirs<'a>(dir: &'a Path) -> Pin<Box<dyn Future<Output = io::Result<()>> + 'a>> {
Box::pin(async move {
if dir.is_dir() {
let mut entries = tokio::fs::read_dir(dir).await?;
while let Some(entry) = entries.next_entry().await? {
let path = entry.path();
if path.is_dir() {
visit_dirs(&path).await?;
// tokio::spawn(visit_dirs(&path));
}
}
}
Ok(())
})
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
visit_dirs(Path::new(".")).await?;
Ok(())
}
The async book has an explanation about why this is required: https://rust-lang.github.io/async-book/07_workarounds/05_recursion.html
1 Like
szopqa
3
Thanks! I saw it but still had a problem to use it in my case. I also found following crate async_recursion - Rust to solve my problem
2 Likes
qaopm
4
FYI there's a handy type alias BoxFuture if you don't want to keep writing
Pin<Box<dyn Future<...> + 'a + Send>>
all the time.
2 Likes
system
Closed
5
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.