macro no-std named-future-proc-macros

Give your Future a name!

3 unstable releases

0.1.0-pre.1 Apr 25, 2023
0.0.2 Apr 25, 2023
0.0.1 Apr 22, 2023

31 downloads per month
Used in named-future

Apache-2.0 WITH LLVM-exception

25KB
443 lines

named-future: Give your Future a name!

GitHub Workflow Status Crates.io Minimum supported Rust version: 1.65 License: Apache-2.0 WITH LLVM-exception

Wrap a Future in a sized struct, so it can be use in traits, or as return type, without the need for Box<>, dyn …, or impl .

A simple workaround until #![feature(type_alias_impl_trait)] is stabilized:

/// A slow multiplication
///
/// # Struct
///
/// Future generated by [`slow_mul`]
#[named_future]
pub async fn slow_mul(factor1: u32, factor2: u32) -> u32 {
    sleep(Duration::from_secs(5)).await;
    factor1 * factor2
}

Expands to:

/// A slow multiplication
pub fn slow_mul(factor1: u32, factor2: u32) -> SlowMul {
    ...
}

/// Future generated by [`slow_mul`]
pub struct SlowMul {
    ...
}

impl Future for SlowMul {
    type Output = u32;

    #[inline]
    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        ...
    }
}

Additionally it will implement a Drop, so a dropped future will work fine, and Debug for your convenience.

The proc_macro #[named_future] has the following optional arguments:

  • #[named_future(Send)]

    • Implement Send for the generated struct. It is currently not possible to detect automatically if the struct should be Send, so you have to ask for the implementation manually. Even so, it is ensured that the Future is send, and the compilation will fail otherwise.
  • #[named_future(Sync)]

    • Implement Sync for the generated struct. Please see the explanation for Send.
  • #[named_future(type = Name)]

    • Instead of the default name, i.e. using pascal case of the function name, you can override the name using this argument. You can also override the visibility of the struct using this argument: type = pub Name. By default, the visibility of the function is copied.
  • #[named_future(crate = some::path)]

    • If you have renamed the dependency in your Cargo.toml, e.g. renamed = { package = "named-future", version = "0.0.1" }, then you have to specify its name / path. Defaults to ::named_future.

To add a documentation to your function, and the generated struct, you can separate both sections with a line /// # Struct

The library code can be used with #![no_std].

Because of limitations in rust, it is currently not possible to implement a “named future” for generic functions: “error: generic Self types are currently not permitted in anonymous constants”.

Inspired by the prior work of Jun Ryung Ju: rename-future

Dependencies

~240–680KB
~16K SLoC