Hi. I'm trying to understand how to create a component which exports a resource in Rust. I may have misunderstandings at every stage, getting confused between guest/host, etc.!
Anyway, from this WIT:
package component:zipreader;
interface zip {
enum zip-error {
unknown
}
resource zipfile {
list-files: func() -> list<string>;
}
}
world zipread {
use zip.{zip-error, zipfile};
export zip;
export open: func(path: string) -> result<zipfile, zip-error>;
}
and using wit-bindgen as:
::wit_bindgen::generate!({
exports: {
world: ZipWorld,
"component:zipreader/zip/zipfile": MyZipfile,
},
});
The generated World
trait is:
pub trait Guest {
fn open(path: wit_bindgen::rt::string::String) -> Result<Zipfile, ZipError>;
}
The open
method needs to return a component::zipreader::zip::Zipfile
, which is a generated type containing a handle: Resource<Zipfile>
. How are you meant to turn an instance of the actual type (MyZipfile
in this example) into the generated type? It seems like something similar to the wasmtime ResourceTable
would fit the bill (or, for my purposes, a Vec<MyZipfile>
would be fine) to get an id - but there's nowhere to store that as the open
doesn't take any self
type. What am I missing?
I believe if you follow the various type aliases you should be able to do Resource::new(MyZipFile::new(...))
, although I agree it's a bit confusing.
If you'd like I just published wit-bindgen 0.20.0 today which I think might simplify this a bit, the exports
field is removed and the compiler error messages and documentation should be a bit clearer about how to implement this. For example Zipfile
, a generated type, will have a function Zipfile::new
.
The 0.20.0 docs have some more documentation so there's an example of bindings for an exported resource which generates this API which should give you a ::new
method where you'll implemente GuestZipfile
for your MyZipfile
type.
Thanks.
There is a Zipfile::new, but it's on exports::component::zipreader::zip::Zipfile
, not component::zipreader::zip::Zipfile
which is a different type and is the one being returned from Guest::open
.
I think, anyway - I'm browsing the output from cargo expand
.
aha I think you'll want to reorganize slightly actually
this is subtle, but the use
statement in your world
is actually importing a different copy of hte zip
interface than the one you're exporting
so the open
function is actually referring to a totally different zipfile
type than the one that you have export
f or
You can read a bit more about this issue at https://github.com/WebAssembly/component-model/pull/308, but more-or-less I'd recommend moving the open
method to the zip
interface
I'll look at that and look more tomorrow. Thanks for the quick responses!
Ok, so just to check my understanding: currently, WIT doesn't support exporting a function from a world, which returns a resource from an exported interface. This will eventually be possible (and is possible in the component model).
Correct!
Last updated: Dec 23 2024 at 13:07 UTC