Skip to content

Improve Rust ergonomics for wasip3 async main functions #110

@wingo

Description

@wingo

It would be nice to write this kind of program:

extern crate wasi;

async fn main() {
    let one_millisecond = 1_000_000u64;
    wasi::clocks::monotonic_clock::wait_for(one_millisecond).await
}

However, there are a number of things that get in the way. Right now you need something like:

extern crate wit_bindgen;

wit_bindgen::generate!({
    inline: r"
  package test:test;

  world test {
      include wasi:clocks/[email protected];
      include wasi:cli/[email protected];
  }
",
    // Work around https://github.com/bytecodealliance/wasm-tools/issues/2285.
    features:["clocks-timezone"],
    async: [
        "wasi:cli/[email protected]#run",
    ],
    generate_all
});

struct Component;
export!(Component);

impl exports::wasi::cli::run::Guest for Component {
    async fn run() -> Result<(), ()> {
        wasi::clocks::monotonic_clock::wait_for(one_millisecond).await
        Ok(())
    }
}

fn main() { unreachable!("main is a stub"); }

Which:

  1. It's weird to have the stub main function
  2. It would be nice to have the same impl std::process::Termination setup for run so we don't have to OK(())
  3. Would be nice to have the wasi::cli::run::Guest implementation produced automatically and just call the async fn main()
  4. Would be nice to avoid having to explicitly declare wasi:cli/run as async when defining async fn main()

Alex mentioned that something like this might be possible, and it seems 95% of the way there:

#[wit_bindgen::async]
async fn main() {}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions