Hello,
I've been looking for an example of this behavior, and if one exists, consider this question answered.
I have a custom Rust runtime using wasmtime to run component model apps/plugins, all of which are so far written in Rust as well and use the same WIT file by running cargo_component_bindings::generate!()
. What I'd like to do next is create a Rust library crate for all of these apps/plugins to deduplicate the boilerplate code that comes along with various serialization steps and trait implementations for the types defined in my WIT file.
When I try to do this by creating a component and use
-ing it in another one, I run into all kinds of issues such as the target/bindings/<package>/target.wasm file being in the wrong place for the 'library' and the component doing the import being seemingly unable to reach code in the other component.
It seems like this might be the wrong strategy to do what I want to do -- is there an idiomatic way to do this kind of thing?
If you want to create a Rust crate that effectively is a wrapper around your bindings (either to provide a higher-level abstraction or extending the functionality of the binding types themselves), you'll probably want to use wit-bindgen
directly from that crate to do so, and then in the component crate, you have it target an empty world and have a normal crate dependency to the bindings crate from your component itself (in theory that should work, but it doesn't have any test coverage)
Thank you, but could you clarify how to use wit-bindgen
to access the functions that my WIT file exposes as "imports"? I can access the types in my interface, but can't find the functions I want to wrap around.
it depends on the imports, but generally they'll generate something like ns::name::iface::func
when the world imports an interface ns:name/iface
and something like world::func
when the world imports a function. i forget the exact paths off the top of my head
i also find using cargo-expand
to see exactly what the generated bindings were helps a little
i have to run and will be back online later
Okay, thanks! I'll try cargo expand
Okay, I've been able to do this strategy successfully now for importing the wrapper and using it in a component. I think it's very close to working, I just have one last problem: Since my wrapper runs wit_bindgen::generate!
, it won't compile unless I handle the exports and impl Guest for Component
.
Then, even though I can impl Guest again in my component that uses the "wrapper", the impl in the wrapper gets used when I use the compiled app in my runtime. Can I set the wrapper up such that it doesn't have to create the Guest, or set up the component so that its Guest gets used in the final thing?
I should clarify that I'm using wasmtime as the runtime for these WASM plugins -- so the runtime is using the generate!
macro in wasmtime::component, but the "library" is using wit_bindgen::generate!
. This seems to be fine in the sense that I can get the library to execute just fine inside the runtime. I think I just need a way to overwrite the impl inside the "library" when I import it into a plugin.
I have a similar (but I think slightly different) use case: I'd like to generate code just for my common WIT types into a shared Rust crate so that I can attach behaviour to them. I'd then want to have several component crates, all with their own worlds, using that shared crate.
Am I right in thinking that wit-bindgen would need to learn some new tricks for this to work? Namely: filter what wit namespaces to generate code for, and also tell it where to find pre-generated code for a given namespace?
Is this something that is already on anyone's radar? If I wanted to have a think about what this might look like, should I open an issue on the wit-bindgen repo with some examples, or better to post it to zulip?
yes, this feature for wit-bindgen landed recently by roman and brian https://github.com/bytecodealliance/wit-bindgen/pull/699
Oh, cool! I'll definitely give this a go. Thanks! :sparkling_heart:
A late response, but I have solved this exact issue by making a rust library that "wraps" the native wit bindgen generated types, adding useful functions, deriving more traits, etc. The individual plugins can then depend on this library and have a much nicer API to work with than if they used the wit bindings directly.
The library I created for this in one of my projects is here, although the code is a bit outdated and would require some changes to update it to the newest version of wit bindgen.
Last updated: Dec 23 2024 at 12:05 UTC