An enum_dispatch alternative that correctly handles impl Future<> trait functions
This repository has been archived on 2026-10-11. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
decduck 4478ec148e
Some checks failed
Release / Create release PR or release (push) Failing after 5s
Rust CI / Formatting (push) Successful in 18s
Rust CI / Test Suite (push) Successful in 23s
Rust CI / Lints (Clippy) (push) Failing after 23s
Rust CI / Check (push) Successful in 23s
Publish / Publish to Forgejo registry (release) Successful in 16s
Fix multi-file
2026-09-19 06:30:20 +00:00
.cargo Add registry 2026-09-19 06:07:06 +00:00
.github/workflows Add workflows 2026-09-19 06:02:40 +00:00
src Fix multi-file 2026-09-19 06:30:20 +00:00
tests Fix multi-file 2026-09-19 06:30:20 +00:00
.gitignore initial commit 2026-09-19 06:00:51 +00:00
Cargo.lock Fix multi-file 2026-09-19 06:30:20 +00:00
Cargo.toml Fix multi-file 2026-09-19 06:30:20 +00:00
README.md Fix multi-file 2026-09-19 06:30:20 +00:00

pneumatic

pneumatic provides static delegation from an enum to the single-field tuple variants it wraps.

use std::future::Future;
use pneumatic::{pneumatic_trait, Pneumatic};

#[pneumatic_trait]
trait Operation {
    fn name(&self) -> String;
    fn run(&self) -> impl Future<Output = String>;
}

#[derive(Pneumatic)]
#[pneumatic(Operation)]
enum Operations {
    First(First),
    Second(Second),
}

The trait attribute records method signatures in a hidden callback macro. The enum derive consumes that method list and creates a match over every variant. Methods returning impl Future<Output = T> become async fn methods returning T; each variant call is awaited inside its match arm.

The enum must use one-field tuple variants, and delegated methods must have a receiver with identifier-pattern arguments. Generic methods are not currently supported. Rust does not allow derive macros on traits, so traits use the pneumatic_trait attribute.

When the trait and enum live in different modules or files, import the trait module with #[macro_use] so the generated method metadata macro is visible to the enum module:

#[macro_use]
mod traits;
mod enums;

Run the example test with:

cargo test