Can I use await inside async recursive functions?

pub async fn send_and_expect(&mut self, request: rtsp_types::Request<Body>, retrying: bool) -> std::result::Result<rtsp_types::Response<Body>, ClientActionError> {

I get:

recursion in an `async fn` requires boxing

recursive `async fn`

note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`rustc(E0733)

I found Recursion - Asynchronous Programming in Rust but it is for a function that does not use async.

What should be the way here?

I found Why recursive async functions require 'static parameters in Rust? - Stack Overflow and I changed my function to

pub fn send_and_expect(&mut self, request: rtsp_types::Request<Body>, retrying: bool) 
-> Pin<Box<dyn Future <Output = std::result::Result<rtsp_types::Response<Body>, ClientActionError>>>> {

but now I cannot use await inside my funtion. Also, how do I return things?

For example:

return Box::pin(Err(ClientActionError::CSeqMissing))

won't work

You need to define a non-async wrapper function in this way:

use futures::future::BoxFuture;

async fn recursive_fn(arg: i32) -> Vec<i32> {
    if arg == 0 {
        return Vec::new();
    }
    
    let mut v = recursive_fn_wrapper(arg - 1).await;
    v.push(arg);
    v
}

fn recursive_fn_wrapper(arg: i32) -> BoxFuture<'static, Vec<i32>> {
    Box::pin(recursive_fn(arg))
}

If the function has non-static references, then connect their lifetime to the BoxFuture like this:

fn recursive_fn_wrapper<'a>(arg: &'a str) -> BoxFuture<'a, Vec<i32>> {
    Box::pin(recursive_fn(arg))
}
1 Like

Better, with one function, using async blocks:

fn recursive_fn_wrapper(arg: i32) -> BoxFuture<'static, Vec<i32>> {
    Box::pin(async move {
        if arg == 0 {
            return Vec::new();
        }
    
        let mut v = recursive_fn_wrapper(arg - 1).await;
        v.push(arg);
        v
    })
}
1 Like