Available on crate feature
runtime
and crate feature component-model
and docsrs
only.Expand description
Example of generating bindings for imported resources in a world.
Notable parts of this example are:
- Imported resources from the host are represented as traits, in this case
HostLogger
. - The per-interface
Host
trait still exists but has a supertrait ofHostLogger
. - Resources are represented as
Resource<T>
and it’s recommended to specify awith
key to indicate what host type you’d like to use for each resource. - A
ResourceTable
can be used to manage resources when working with guests.
use wasmtime::Result;
use wasmtime::component::{bindgen, ResourceTable, Resource};
use example::imported_resources::logging::{Level, Host, HostLogger};
bindgen!({
inline: r#"
package example:imported-resources;
interface logging {
enum level {
debug,
info,
warn,
error,
}
resource logger {
constructor(max-level: level);
get-max-level: func() -> level;
set-max-level: func(level: level);
log: func(level: level, msg: string);
}
}
world import-some-resources {
import logging;
}
"#,
with: {
// Specify that our host resource is going to point to the `MyLogger`
// which is defined just below this macro.
"example:imported-resources/logging/logger": MyLogger,
},
// Interactions with `ResourceTable` can possibly trap so enable the ability
// to return traps from generated functions.
trappable_imports: true,
});
/// A sample host-defined type which contains arbitrary host-defined data.
///
/// In this case this is relatively simple but there's no restrictions on what
/// this type can hold other than that it must be `'static + Send`.
pub struct MyLogger {
pub max_level: example::imported_resources::logging::Level,
}
#[derive(Default)]
struct MyState {
// Manages the mapping of `MyLogger` structures to `Resource<MyLogger>`.
table: ResourceTable,
}
// There are no free-functions on `interface logging`, so this is an empty
// impl.
impl Host for MyState {}
// This separate `HostLogger` trait serves to act as a namespace for just
// the `logger`-related resource methods.
impl HostLogger for MyState {
// A `constructor` in WIT maps to a `new` function in Rust.
fn new(&mut self, max_level: Level) -> Result<Resource<MyLogger>> {
let id = self.table.push(MyLogger { max_level })?;
Ok(id)
}
fn get_max_level(&mut self, logger: Resource<MyLogger>) -> Result<Level> {
debug_assert!(!logger.owned());
let logger = self.table.get(&logger)?;
Ok(logger.max_level)
}
fn set_max_level(&mut self, logger: Resource<MyLogger>, level: Level) -> Result<()> {
debug_assert!(!logger.owned());
let logger = self.table.get_mut(&logger)?;
logger.max_level = level;
Ok(())
}
fn log(&mut self, logger: Resource<MyLogger>, level: Level, msg: String) -> Result<()> {
debug_assert!(!logger.owned());
let logger = self.table.get_mut(&logger)?;
if (level as u32) <= (logger.max_level as u32) {
println!("{msg}");
}
Ok(())
}
fn drop(&mut self, logger: Resource<MyLogger>) -> Result<()> {
debug_assert!(logger.owned());
let _logger: MyLogger = self.table.delete(logger)?;
// ... custom destruction logic here if necessary, otherwise
// a `Drop for MyLogger` would also work.
Ok(())
}
}
Modules§
Structs§
- Auto-generated bindings for an instance a component which implements the world
import-some-resources
. - Auto-generated bindings for index of the exports of
import-some-resources
. - Auto-generated bindings for a pre-instantiated version of a component which implements the world
import-some-resources
. - A sample host-defined type which contains arbitrary host-defined data.