Hii!
I'm playing around with a toy web browser in which a fictitious Web API is defined in WIT. Let's call that interface wawi
:3
A tiny wit
world so far been created that defines a print(message: string)
import and main()
export that works well with wit_bindgen::generate!
for the guest implementation and wasmtime::component::bindgen!
for the host implementation.
Thing is, it seems like the Guest
implementation has to be done in the module where the generate!()
invocation is made. But I'm only interested in it generating the imports, and then have an external crate implement the exports. Something that might be similar to this:
// crate `wawi`:
pub use wawi_internal::wawi;
pub use wawi_internal::Guest as App;
mod wawi_internal {
wit_bindgen::generate!({
path: "../../wawi-wit",
world: "wawi",
});
}
// wawi dependant crate: `webb_app`
use ::wawi::{wawi, App};
struct MyWebApp;
impl App for MyWebApp {
fn main() {
wawi::dom::print::println("Hello, wawi!");
}
}
As you probably know, this won't work since the extern "C" main()
is expanded by generate!
. But I was able to work around this by moving the expanded code over to webb_app
, without it explicitly depending on wit-bindgen
:
use ::wawi::{wawi, App};
struct MyWebApp;
impl App for MyWebApp {
fn main() {
wawi::dom::print::println("Hello, Wawi!");
}
}
const _: () = {
#[doc(hidden)]
#[export_name = "main"]
#[allow(non_snake_case)]
unsafe extern "C" fn __export_main() {
#[allow(unused_imports)]
use ::wawi::runtime::{alloc, String, Vec};
#[cfg(target_arch = "wasm32")]
::wawi::runtime::run_ctors_once();
MyWebApp::main()
}
};
// crate `wawi`:
pub use wawi_internal::wawi;
pub use wawi_internal::Guest as App;
pub mod runtime {
#[cfg(target_arch = "wasm32")]
pub use wit_bindgen::rt::{alloc, run_ctors_once, string::String, vec::Vec};
}
// ...
Clearly, this won't scale as is, hence the following questions :see_no_evil:
wit-bindgen
by forcing it to do something it was never intended to do?Would love to hear your input/tips on resources I could look into.
Thanks :blush:
For imports/exports I think that may be fixable by adding more features to the macro. For example in Wasmtime we have the ability to generate WASI types in one crate and then use those from other crates. That feature hasn't been ported to the guest Rust macro yet though, so it'd take some work.
For having a trait that a different crate implements I think the short answer is that it's basically not great right now. I'd recommend looking into what cargo component
generates since that's solving a similar problem, although its solution may be derivative of the fact that it controls more of the compilation process than a simpler crate dependency. More-or-less I think we're still iterating on this space of how to get the user to implement a set of exported functions and have that registered with WIT exports
this also affects me so I made an issue: https://github.com/bytecodealliance/wit-bindgen/issues/674
Last updated: Dec 23 2024 at 12:05 UTC