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/imports@0.3.0-rc-2025-08-15;
include wasi:cli/command@0.3.0-rc-2025-08-15;
}
",
// Work around https://github.com/bytecodealliance/wasm-tools/issues/2285.
features:["clocks-timezone"],
async: [
"wasi:cli/run@0.3.0-rc-2025-08-15#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:
- It's weird to have the stub main function
- It would be nice to have the same
impl std::process::Termination setup for run so we don't have to OK(())
- Would be nice to have the
wasi::cli::run::Guest implementation produced automatically and just call the async fn main()
- 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() {}
It would be nice to write this kind of program:
However, there are a number of things that get in the way. Right now you need something like:
Which:
impl std::process::Terminationsetup forrunso we don't have toOK(())wasi::cli::run::Guestimplementation produced automatically and just call theasync fn main()wasi:cli/runas async when definingasync fn main()Alex mentioned that something like this might be possible, and it seems 95% of the way there: