Skip to content

Repository files navigation

async-recursion macro

Latest versioncrates.io downloadsBuild StatusApache/MIT2.0 License

Procedural macro for recursive async functions.

Motivation

Consider the following recursive implementation of the fibonacci numbers:

asyncfnfib(n:u32) -> u32{match n {0 | 1 => 1,
_ => fib(n-1).await + fib(n-2).await}}

The compiler helpfully tells us that:

error[E0733]: recursion in an `async fn` requires boxing --> src/main.rs:1:26 |1 | async fn fib(n : u32) -> u32 { | ^^^ recursive `async fn` | = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion

This crate provides an attribute macro to automatically convert an async function to one returning a boxed Future.

Example

use async_recursion::async_recursion;#[async_recursion]asyncfnfib(n:u32) -> u32{match n {0 | 1 => 1,
_ => fib(n-1).await + fib(n-2).await}}

?Send option

The returned Future has a Send bound to make sure it can be sent between threads. If this is undesirable you can mark that the bound should be left out like so:

#[async_recursion(?Send)]asyncfnreturned_future_is_not_send(){// ...}

Sync option

The returned Future doesn't have a Sync bound as it is usually not required. You can include a Sync bound as follows:

#[async_recursion(Sync)]asyncfnreturned_future_is_sync(){// ...}

In detail:

  • #[async_recursion] modifies your function to return a boxed Future with a Send bound.
  • #[async_recursion(?Send)] modifies your function to return a boxed Futurewithout a Send bound.
  • #[async_recursion(Sync)] modifies your function to return a boxed Future with a Send and Sync bound.

License

Licensed under either of

at your option.

About

Procedural macro for recursive async functions

Resources

Stars

239 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages