144220746SAlex Crichton //! Examples of output of the [`bindgen!`] macro. 244220746SAlex Crichton //! 344220746SAlex Crichton //! This module is only included in docs.rs documentation and is not present in 444220746SAlex Crichton //! the actual crate when compiling from crates.io. The purpose of this module 544220746SAlex Crichton //! is to showcase what the output of the [`bindgen!`] macro looks like and some 644220746SAlex Crichton //! examples of how to use it. 744220746SAlex Crichton //! 844220746SAlex Crichton //! If you're confused or lost in [`bindgen!`] feel free to [open an issue] 944220746SAlex Crichton //! with a description of your issue and it can hopefully lead to a new example 1044220746SAlex Crichton //! being added here for others to use as reference. 1144220746SAlex Crichton //! 1244220746SAlex Crichton //! ## Including `*.wit` files in your project 1344220746SAlex Crichton //! 1444220746SAlex Crichton //! Note that most of the examples in this module will use the `inline` key of 1544220746SAlex Crichton //! the [`bindgen!`] macro. This is done as it's easy to show the example and 1644220746SAlex Crichton //! WIT all in one self-contained snippet of Rust code. Typically though a 1744220746SAlex Crichton //! project will have a `wit` directory next to `Cargo.toml` which contains WIT 1844220746SAlex Crichton //! files. 1944220746SAlex Crichton //! 2044220746SAlex Crichton //! The general layout of a `wit` directory is that: 2144220746SAlex Crichton //! 2244220746SAlex Crichton //! * All `*.wit` files at `wit/*.wit` are parsed and included in the same 2344220746SAlex Crichton //! package. 2444220746SAlex Crichton //! * If the `wit/deps` folder is present then it can either contain: 2544220746SAlex Crichton //! * Subdirectories with a package-per-directory. For example 2644220746SAlex Crichton //! `wit/deps/wasi-http` and `wit/deps/wasi-cli`. 2744220746SAlex Crichton //! * WIT files that are a single-file rendering of a package, for example 2844220746SAlex Crichton //! `wit/deps/wasi-http.wit` 2944220746SAlex Crichton //! * WIT packages encoded as WebAssembly binaries for a package, for example 3044220746SAlex Crichton //! `wit/deps/wasi-http.wasm` 3144220746SAlex Crichton //! 3244220746SAlex Crichton //! This means that at this time you'll need to copy around `*.wit` files or 3344220746SAlex Crichton //! WIT packages encoded as `*.wasm` and check them in to your project's `wit` 3444220746SAlex Crichton //! directory. The hope is that in the future it will be easier to manage these 3544220746SAlex Crichton //! files with registry tooling and they won't have to be copied manually. 3644220746SAlex Crichton //! For reference documentation on the layout of the `wit` directory see 3744220746SAlex Crichton //! [`wit_parser::Resolve::push_dir`]. 3844220746SAlex Crichton //! 3944220746SAlex Crichton //! [`bindgen!`]: crate::component::bindgen 4044220746SAlex Crichton //! [`wit_parser::Resolve::push_dir`]: https://docs.rs/wit-parser/latest/wit_parser/struct.Resolve.html#method.push_dir 4144220746SAlex Crichton //! [open an issue]: https://github.com/bytecodealliance/wasmtime/issues/new 4244220746SAlex Crichton 43838ed2d0SAlex Crichton #![expect( 44838ed2d0SAlex Crichton missing_docs, 45838ed2d0SAlex Crichton reason = "bindgen-generated types known to not have docs" 46838ed2d0SAlex Crichton )] 4744220746SAlex Crichton 4844220746SAlex Crichton // This "hack" will shadow the `bindgen` macro in general and be inherited to 4944220746SAlex Crichton // following modules by default. This enables documenting sources as-is while 5044220746SAlex Crichton // additionally customizing them to working within the wasmtime crate itself by 5144220746SAlex Crichton // injecting a configuration option to change how the `wasmtime` crate is 5244220746SAlex Crichton // referenced in the generated output. 5344220746SAlex Crichton // 5444220746SAlex Crichton // Note that this has an additional "hack" such that when docs.rs is documenting 5544220746SAlex Crichton // this crate (or CI) then `include_generated_code_from_file` is unconditionally 5644220746SAlex Crichton // turned on. This makes `[source]` links on documentation show the actual 5744220746SAlex Crichton // generated code rather than just the `bindgen!` macro invocation, which can be 5844220746SAlex Crichton // helpful when exploring code. 5944220746SAlex Crichton #[cfg(docsrs)] 6044220746SAlex Crichton macro_rules! bindgen { 6144220746SAlex Crichton ({$($t:tt)*}) => (crate::component::bindgen!({ 6244220746SAlex Crichton $($t)* 6344220746SAlex Crichton wasmtime_crate: crate, 6444220746SAlex Crichton include_generated_code_from_file: true, 6544220746SAlex Crichton });); 6644220746SAlex Crichton } 6744220746SAlex Crichton #[cfg(not(docsrs))] 6844220746SAlex Crichton macro_rules! bindgen { 6944220746SAlex Crichton ({$($t:tt)*}) => (crate::component::bindgen!({ 7044220746SAlex Crichton $($t)* 7144220746SAlex Crichton wasmtime_crate: crate, 7244220746SAlex Crichton });); 7344220746SAlex Crichton } 7444220746SAlex Crichton 7544220746SAlex Crichton /// A "hello world" style example. 7644220746SAlex Crichton /// 7744220746SAlex Crichton /// This example loads a component which has access to a single host function. 7844220746SAlex Crichton /// The exported function is called on an instantiation of the component. 7944220746SAlex Crichton /// 8044220746SAlex Crichton /// ```rust 8144220746SAlex Crichton /// use wasmtime::component::*; 8244220746SAlex Crichton /// use wasmtime::{Engine, Store}; 8344220746SAlex Crichton /// 8444220746SAlex Crichton #[doc = include_str!("./_0_hello_world.rs")] 8544220746SAlex Crichton /// 8644220746SAlex Crichton /// struct MyState { 8744220746SAlex Crichton /// name: String, 8844220746SAlex Crichton /// } 8944220746SAlex Crichton /// 9044220746SAlex Crichton /// // Imports into the world, like the `name` import for this world, are 9144220746SAlex Crichton /// // satisfied through traits. 9244220746SAlex Crichton /// impl HelloWorldImports for MyState { 9344220746SAlex Crichton /// fn name(&mut self) -> String { 9444220746SAlex Crichton /// self.name.clone() 9544220746SAlex Crichton /// } 9644220746SAlex Crichton /// } 9744220746SAlex Crichton /// 9844220746SAlex Crichton /// fn main() -> wasmtime::Result<()> { 9944220746SAlex Crichton /// # if true { return Ok(()) } 10044220746SAlex Crichton /// // Compile the `Component` that is being run for the application. 10144220746SAlex Crichton /// let engine = Engine::default(); 10244220746SAlex Crichton /// let component = Component::from_file(&engine, "./your-component.wasm")?; 10344220746SAlex Crichton /// 10444220746SAlex Crichton /// // Instantiation of bindings always happens through a `Linker`. 10544220746SAlex Crichton /// // Configuration of the linker is done through a generated `add_to_linker` 10644220746SAlex Crichton /// // method on the bindings structure. 10744220746SAlex Crichton /// // 108f6775a33SAlex Crichton /// // Note that the function provided here is a projection from `T` in 10944220746SAlex Crichton /// // `Store<T>` to `&mut U` where `U` implements the `HelloWorldImports` 11044220746SAlex Crichton /// // trait. In this case the `T`, `MyState`, is stored directly in the 11144220746SAlex Crichton /// // structure so no projection is necessary here. 112f6775a33SAlex Crichton /// // 113f6775a33SAlex Crichton /// // Note that the second type parameter of `add_to_linker` is chosen here 114f6775a33SAlex Crichton /// // as the built-in `HasSelf` type in Wasmtime. This effectively says 115f6775a33SAlex Crichton /// // that our function isn't actually projecting, it's returning the 116f6775a33SAlex Crichton /// // input, so `HasSelf<_>` is a convenience to avoid writing a custom 117f6775a33SAlex Crichton /// // `HasData` implementation. 11844220746SAlex Crichton /// let mut linker = Linker::new(&engine); 119f6775a33SAlex Crichton /// HelloWorld::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 12044220746SAlex Crichton /// 12144220746SAlex Crichton /// // As with the core wasm API of Wasmtime instantiation occurs within a 12244220746SAlex Crichton /// // `Store`. The bindings structure contains an `instantiate` method which 12344220746SAlex Crichton /// // takes the store, component, and linker. This returns the `bindings` 12444220746SAlex Crichton /// // structure which is an instance of `HelloWorld` and supports typed access 12544220746SAlex Crichton /// // to the exports of the component. 12644220746SAlex Crichton /// let mut store = Store::new( 12744220746SAlex Crichton /// &engine, 12844220746SAlex Crichton /// MyState { 12944220746SAlex Crichton /// name: "me".to_string(), 13044220746SAlex Crichton /// }, 13144220746SAlex Crichton /// ); 1323171ef6dSAlex Crichton /// let bindings = HelloWorld::instantiate(&mut store, &component, &linker)?; 13344220746SAlex Crichton /// 13444220746SAlex Crichton /// // Here our `greet` function doesn't take any parameters for the component, 13544220746SAlex Crichton /// // but in the Wasmtime embedding API the first argument is always a `Store`. 13644220746SAlex Crichton /// bindings.call_greet(&mut store)?; 13744220746SAlex Crichton /// Ok(()) 13844220746SAlex Crichton /// } 13944220746SAlex Crichton /// ``` 14044220746SAlex Crichton pub mod _0_hello_world; 14144220746SAlex Crichton 14244220746SAlex Crichton /// An example of generated bindings for top-level imported functions and 14344220746SAlex Crichton /// interfaces into a world. 14444220746SAlex Crichton /// 14544220746SAlex Crichton /// The code used to generate this module is: 14644220746SAlex Crichton /// 14744220746SAlex Crichton /// ```rust 14844220746SAlex Crichton /// use wasmtime::component::*; 14944220746SAlex Crichton /// use wasmtime::{Engine, Store}; 15044220746SAlex Crichton /// 15144220746SAlex Crichton #[doc = include_str!("./_1_world_imports.rs")] 15244220746SAlex Crichton /// 15344220746SAlex Crichton /// struct MyState { 15444220746SAlex Crichton /// // ... 15544220746SAlex Crichton /// } 15644220746SAlex Crichton /// 15744220746SAlex Crichton /// impl my_custom_host::Host for MyState { 15844220746SAlex Crichton /// fn tick(&mut self) { 15944220746SAlex Crichton /// todo!() 16044220746SAlex Crichton /// } 16144220746SAlex Crichton /// } 16244220746SAlex Crichton /// 16344220746SAlex Crichton /// impl MyWorldImports for MyState { 16444220746SAlex Crichton /// fn greet(&mut self) -> String { 16544220746SAlex Crichton /// todo!() 16644220746SAlex Crichton /// } 16744220746SAlex Crichton /// 16844220746SAlex Crichton /// fn log(&mut self, msg: String) { 16944220746SAlex Crichton /// println!("{msg}"); 17044220746SAlex Crichton /// } 17144220746SAlex Crichton /// } 17244220746SAlex Crichton /// 17344220746SAlex Crichton /// fn main() -> wasmtime::Result<()> { 17444220746SAlex Crichton /// # if true { return Ok(()) } 17544220746SAlex Crichton /// let engine = Engine::default(); 17644220746SAlex Crichton /// let component = Component::from_file(&engine, "./your-component.wasm")?; 17744220746SAlex Crichton /// 17844220746SAlex Crichton /// let mut linker = Linker::new(&engine); 179f6775a33SAlex Crichton /// MyWorld::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 18044220746SAlex Crichton /// 18144220746SAlex Crichton /// let mut store = Store::new( 18244220746SAlex Crichton /// &engine, 18344220746SAlex Crichton /// MyState { /* ... */ }, 18444220746SAlex Crichton /// ); 1853171ef6dSAlex Crichton /// let bindings = MyWorld::instantiate(&mut store, &component, &linker)?; 18644220746SAlex Crichton /// 18744220746SAlex Crichton /// // ... NB: this world has no exports just yet so not much can be done 18844220746SAlex Crichton /// // with `bindings`. 18944220746SAlex Crichton /// 19044220746SAlex Crichton /// Ok(()) 19144220746SAlex Crichton /// } 19244220746SAlex Crichton /// ``` 19344220746SAlex Crichton pub mod _1_world_imports; 19444220746SAlex Crichton 19544220746SAlex Crichton /// An example of generated bindings for top-level exported functions for a 19644220746SAlex Crichton /// world. 19744220746SAlex Crichton /// 19844220746SAlex Crichton /// Some notable generated items here are: 19944220746SAlex Crichton /// 20044220746SAlex Crichton /// * [`my::project::host::Host`](_2_world_exports::my::project::host::Host) - 20144220746SAlex Crichton /// the generated trait for the `interface host` import. 20244220746SAlex Crichton /// * [`exports::demo::Guest`](_2_world_exports::exports::demo::Guest) - 20344220746SAlex Crichton /// the generated structured used to invoke exports on the returned instance. 20444220746SAlex Crichton /// * [`HelloWorld`](_2_world_exports::HelloWorld) - 20544220746SAlex Crichton /// the overall generated structure representing our `world`. 20644220746SAlex Crichton /// 20744220746SAlex Crichton /// ```rust 20844220746SAlex Crichton /// use wasmtime::component::*; 20944220746SAlex Crichton /// use wasmtime::{Engine, Store}; 21044220746SAlex Crichton /// 21144220746SAlex Crichton #[doc = include_str!("./_2_world_exports.rs")] 21244220746SAlex Crichton /// 21344220746SAlex Crichton /// struct MyState { 21444220746SAlex Crichton /// // ... 21544220746SAlex Crichton /// } 21644220746SAlex Crichton /// 2179e46e78aSAlex Crichton /// # mod rand { pub fn thread_rng() -> G { G } pub struct G; impl G { pub fn r#gen(&self) -> u32 { 0 } } } 21844220746SAlex Crichton /// // Note that the trait here is per-interface and within a submodule now. 21944220746SAlex Crichton /// impl my::project::host::Host for MyState { 22044220746SAlex Crichton /// fn gen_random_integer(&mut self) -> u32 { 2219e46e78aSAlex Crichton /// rand::thread_rng().r#gen() 22244220746SAlex Crichton /// } 22344220746SAlex Crichton /// 22444220746SAlex Crichton /// fn sha256(&mut self, bytes: Vec<u8>) -> String { 22544220746SAlex Crichton /// // ... 22644220746SAlex Crichton /// # panic!() 22744220746SAlex Crichton /// } 22844220746SAlex Crichton /// } 22944220746SAlex Crichton /// 23044220746SAlex Crichton /// fn main() -> wasmtime::Result<()> { 23144220746SAlex Crichton /// # if true { return Ok(()) } 23244220746SAlex Crichton /// let engine = Engine::default(); 23344220746SAlex Crichton /// let component = Component::from_file(&engine, "./your-component.wasm")?; 23444220746SAlex Crichton /// 23544220746SAlex Crichton /// let mut linker = Linker::new(&engine); 236f6775a33SAlex Crichton /// HelloWorld::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 23744220746SAlex Crichton /// 23844220746SAlex Crichton /// let mut store = Store::new( 23944220746SAlex Crichton /// &engine, 24044220746SAlex Crichton /// MyState { /* ... */ }, 24144220746SAlex Crichton /// ); 2423171ef6dSAlex Crichton /// let bindings = HelloWorld::instantiate(&mut store, &component, &linker)?; 24344220746SAlex Crichton /// 24444220746SAlex Crichton /// // Note that the `demo` method returns a `&exports::Demo::Guest` 24544220746SAlex Crichton /// // through which we can run the methods on that interface. 24644220746SAlex Crichton /// bindings.demo().call_run(&mut store)?; 24744220746SAlex Crichton /// Ok(()) 24844220746SAlex Crichton /// } 24944220746SAlex Crichton /// ``` 25044220746SAlex Crichton pub mod _2_world_exports; 25144220746SAlex Crichton 25244220746SAlex Crichton /// Example of generating bindings for imported interfaces in a world. 25344220746SAlex Crichton /// 25444220746SAlex Crichton /// Notable parts of this example are: 25544220746SAlex Crichton /// 25644220746SAlex Crichton /// * Imported interfaces use the Rust module system to encapsulate themselves. 25744220746SAlex Crichton /// The interface imported here is `example:interface-imports/logging` so the 25844220746SAlex Crichton /// generated trait and types are located in 25944220746SAlex Crichton /// [`example::interface_imports::logging`][module]. 26044220746SAlex Crichton /// * Types in the `logging` interface are generated in the `logging` module, 26144220746SAlex Crichton /// for example [`Level`]. 26244220746SAlex Crichton /// * Generated types have implementations of [`ComponentType`], [`Lift`], and 26344220746SAlex Crichton /// [`Lower`] derived. 26444220746SAlex Crichton /// * The generated trait that host's must implement is always called [`Host`] 26544220746SAlex Crichton /// and is located in the generated module. 26644220746SAlex Crichton /// 26744220746SAlex Crichton /// [module]: _3_interface_imports::example::interface_imports::logging 26844220746SAlex Crichton /// [`Level`]: _3_interface_imports::example::interface_imports::logging::Level 26944220746SAlex Crichton /// [`Host`]: _3_interface_imports::example::interface_imports::logging::Host 27044220746SAlex Crichton /// [`ComponentType`]: crate::component::ComponentType 27144220746SAlex Crichton /// [`Lift`]: crate::component::Lift 27244220746SAlex Crichton /// [`Lower`]: crate::component::Lower 27344220746SAlex Crichton /// 27444220746SAlex Crichton /// ```rust 27544220746SAlex Crichton /// use wasmtime::component::bindgen; 27644220746SAlex Crichton /// use example::interface_imports::logging::Level; 27744220746SAlex Crichton /// 27844220746SAlex Crichton #[doc = include_str!("./_3_interface_imports.rs")] 27944220746SAlex Crichton /// 28044220746SAlex Crichton /// struct MyState { 28144220746SAlex Crichton /// // ... 28244220746SAlex Crichton /// } 28344220746SAlex Crichton /// 28444220746SAlex Crichton /// impl example::interface_imports::logging::Host for MyState { 28544220746SAlex Crichton /// fn log(&mut self, level: Level, msg: String) { 28644220746SAlex Crichton /// // ... 28744220746SAlex Crichton /// } 28844220746SAlex Crichton /// } 28944220746SAlex Crichton /// ``` 29044220746SAlex Crichton pub mod _3_interface_imports; 29144220746SAlex Crichton 29244220746SAlex Crichton /// Example of generating bindings for imported resources in a world. 29344220746SAlex Crichton /// 29444220746SAlex Crichton /// Notable parts of this example are: 29544220746SAlex Crichton /// 29644220746SAlex Crichton /// * Imported resources from the host are represented as traits, in this case 29744220746SAlex Crichton /// [`HostLogger`]. 29844220746SAlex Crichton /// * The per-interface [`Host`] trait still exists but has a supertrait of 29944220746SAlex Crichton /// [`HostLogger`]. 30044220746SAlex Crichton /// * Resources are represented as [`Resource<T>`] and it's recommended to 30144220746SAlex Crichton /// specify a `with` key to indicate what host type you'd like to use for 30244220746SAlex Crichton /// each resource. 30344220746SAlex Crichton /// * A [`ResourceTable`] can be used to manage resources when working with 30444220746SAlex Crichton /// guests. 30544220746SAlex Crichton /// 30644220746SAlex Crichton /// [`Host`]: _4_imported_resources::example::imported_resources::logging::Host 30744220746SAlex Crichton /// [`HostLogger`]: _4_imported_resources::example::imported_resources::logging::HostLogger 30844220746SAlex Crichton /// [`Resource<T>`]: crate::component::Resource 30944220746SAlex Crichton /// [`ResourceTable`]: crate::component::ResourceTable 31044220746SAlex Crichton /// 31144220746SAlex Crichton /// ```rust 31244220746SAlex Crichton /// use wasmtime::Result; 31344220746SAlex Crichton /// use wasmtime::component::{bindgen, ResourceTable, Resource}; 31444220746SAlex Crichton /// use example::imported_resources::logging::{Level, Host, HostLogger}; 31544220746SAlex Crichton /// 31644220746SAlex Crichton #[doc = include_str!("./_4_imported_resources.rs")] 31744220746SAlex Crichton /// 31844220746SAlex Crichton /// #[derive(Default)] 31944220746SAlex Crichton /// struct MyState { 32044220746SAlex Crichton /// // Manages the mapping of `MyLogger` structures to `Resource<MyLogger>`. 32144220746SAlex Crichton /// table: ResourceTable, 32244220746SAlex Crichton /// } 32344220746SAlex Crichton /// 32444220746SAlex Crichton /// // There are no free-functions on `interface logging`, so this is an empty 32544220746SAlex Crichton /// // impl. 32644220746SAlex Crichton /// impl Host for MyState {} 32744220746SAlex Crichton /// 32844220746SAlex Crichton /// // This separate `HostLogger` trait serves to act as a namespace for just 32944220746SAlex Crichton /// // the `logger`-related resource methods. 33044220746SAlex Crichton /// impl HostLogger for MyState { 33144220746SAlex Crichton /// // A `constructor` in WIT maps to a `new` function in Rust. 33244220746SAlex Crichton /// fn new(&mut self, max_level: Level) -> Result<Resource<MyLogger>> { 33344220746SAlex Crichton /// let id = self.table.push(MyLogger { max_level })?; 33444220746SAlex Crichton /// Ok(id) 33544220746SAlex Crichton /// } 33644220746SAlex Crichton /// 33744220746SAlex Crichton /// fn get_max_level(&mut self, logger: Resource<MyLogger>) -> Result<Level> { 33844220746SAlex Crichton /// debug_assert!(!logger.owned()); 33944220746SAlex Crichton /// let logger = self.table.get(&logger)?; 34044220746SAlex Crichton /// Ok(logger.max_level) 34144220746SAlex Crichton /// } 34244220746SAlex Crichton /// 34344220746SAlex Crichton /// fn set_max_level(&mut self, logger: Resource<MyLogger>, level: Level) -> Result<()> { 34444220746SAlex Crichton /// debug_assert!(!logger.owned()); 34544220746SAlex Crichton /// let logger = self.table.get_mut(&logger)?; 34644220746SAlex Crichton /// logger.max_level = level; 34744220746SAlex Crichton /// Ok(()) 34844220746SAlex Crichton /// } 34944220746SAlex Crichton /// 35044220746SAlex Crichton /// fn log(&mut self, logger: Resource<MyLogger>, level: Level, msg: String) -> Result<()> { 35144220746SAlex Crichton /// debug_assert!(!logger.owned()); 35244220746SAlex Crichton /// let logger = self.table.get_mut(&logger)?; 35344220746SAlex Crichton /// if (level as u32) <= (logger.max_level as u32) { 35444220746SAlex Crichton /// println!("{msg}"); 35544220746SAlex Crichton /// } 35644220746SAlex Crichton /// Ok(()) 35744220746SAlex Crichton /// } 35844220746SAlex Crichton /// 35944220746SAlex Crichton /// fn drop(&mut self, logger: Resource<MyLogger>) -> Result<()> { 36044220746SAlex Crichton /// debug_assert!(logger.owned()); 36144220746SAlex Crichton /// let _logger: MyLogger = self.table.delete(logger)?; 36244220746SAlex Crichton /// // ... custom destruction logic here if necessary, otherwise 36344220746SAlex Crichton /// // a `Drop for MyLogger` would also work. 36444220746SAlex Crichton /// Ok(()) 36544220746SAlex Crichton /// } 36644220746SAlex Crichton /// } 36744220746SAlex Crichton /// 36844220746SAlex Crichton /// # fn main() {} 36944220746SAlex Crichton /// ``` 37044220746SAlex Crichton pub mod _4_imported_resources; 37144220746SAlex Crichton 37244220746SAlex Crichton /// Example of all kinds of structures of exports from a world. 37344220746SAlex Crichton /// 37444220746SAlex Crichton /// * Top-level functions in a `world` are exported directly on the generated 37544220746SAlex Crichton /// structure such as [`call_run`]. 37644220746SAlex Crichton /// * All other exports are otherwise scoped with generated traits/types 37744220746SAlex Crichton /// in a top level [`exports`] module. 37844220746SAlex Crichton /// * Exported named interfaces are located at the root of the [`exports`] 37944220746SAlex Crichton /// module, such as [`exports::environment`]. 38044220746SAlex Crichton /// * Interfaces are all bound with a structure called `Guest` which has typed 38144220746SAlex Crichton /// functions for each export that can be called. For example 38244220746SAlex Crichton /// [`exports::environment::Guest`][guest1] and 38344220746SAlex Crichton /// [`exports::example::world_exports::units::Guest`][guest2]. 38444220746SAlex Crichton /// * Interfaces exported by their id are modeled with multiple namespacing 38544220746SAlex Crichton /// modules, such as [`exports::example::world_exports::units`][units]. 38644220746SAlex Crichton /// 38744220746SAlex Crichton /// [`call_run`]: _5_all_world_export_kinds::WithExports::call_run 38844220746SAlex Crichton /// [`exports`]: _5_all_world_export_kinds::exports 38944220746SAlex Crichton /// [`exports::environment`]: _5_all_world_export_kinds::exports::environment 39044220746SAlex Crichton /// [guest1]: _5_all_world_export_kinds::exports::environment::Guest 39144220746SAlex Crichton /// [guest2]: _5_all_world_export_kinds::exports::example::world_exports::units::Guest 39244220746SAlex Crichton /// [units]: _5_all_world_export_kinds::exports::example::world_exports::units 39344220746SAlex Crichton /// 39444220746SAlex Crichton /// ```rust 39544220746SAlex Crichton /// use wasmtime::{Result, Engine, Store}; 396f6775a33SAlex Crichton /// use wasmtime::component::{bindgen, Component, Linker, HasSelf}; 39744220746SAlex Crichton /// 39844220746SAlex Crichton #[doc = include_str!("./_5_all_world_export_kinds.rs")] 39944220746SAlex Crichton /// 40044220746SAlex Crichton /// struct MyState; 40144220746SAlex Crichton /// 40244220746SAlex Crichton /// impl WithExportsImports for MyState { 40344220746SAlex Crichton /// fn log(&mut self, msg: String) { 40444220746SAlex Crichton /// println!("{msg}"); 40544220746SAlex Crichton /// } 40644220746SAlex Crichton /// } 40744220746SAlex Crichton /// 40844220746SAlex Crichton /// fn main() -> Result<()> { 40944220746SAlex Crichton /// # if true { return Ok(()) } 41044220746SAlex Crichton /// let engine = Engine::default(); 41144220746SAlex Crichton /// let component = Component::from_file(&engine, "./your-component.wasm")?; 41244220746SAlex Crichton /// 41344220746SAlex Crichton /// let mut linker = Linker::new(&engine); 414f6775a33SAlex Crichton /// WithExports::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 41544220746SAlex Crichton /// 41644220746SAlex Crichton /// let mut store = Store::new(&engine, MyState); 4173171ef6dSAlex Crichton /// let bindings = WithExports::instantiate(&mut store, &component, &linker)?; 41844220746SAlex Crichton /// 41944220746SAlex Crichton /// // top-level functions are exported directly on `WithExports` and are 42044220746SAlex Crichton /// // all prefixed with `call_*`. 42144220746SAlex Crichton /// bindings.call_run(&mut store)?; 42244220746SAlex Crichton /// 42344220746SAlex Crichton /// // exported named interfaces are named directly after their export name 42444220746SAlex Crichton /// // and the `&Guest` return value has `call_*` functions on it. 42544220746SAlex Crichton /// bindings.environment().call_set(&mut store, "key", "value")?; 42644220746SAlex Crichton /// let value = bindings.environment().call_get(&mut store, "key")?; 42744220746SAlex Crichton /// assert_eq!(value, "value"); 42844220746SAlex Crichton /// 42944220746SAlex Crichton /// // exported interfaces by id are similar to export-by-name except that 43044220746SAlex Crichton /// // the exported name is modeled after the full id, not just the name. 43144220746SAlex Crichton /// let units = bindings.example_world_exports_units(); 43244220746SAlex Crichton /// let bytes = 1 << 30 + 1 << 20; 43344220746SAlex Crichton /// let s = units.call_bytes_to_string(&mut store, bytes)?; 43444220746SAlex Crichton /// println!("{bytes} = {s}"); 43544220746SAlex Crichton /// 43644220746SAlex Crichton /// let (seconds, ns) = (1 << 20, 12345); 43744220746SAlex Crichton /// let s = units.call_duration_to_string(&mut store, seconds, ns)?; 43844220746SAlex Crichton /// println!("{seconds}s + {ns}ns = {s}"); 43944220746SAlex Crichton /// Ok(()) 44044220746SAlex Crichton /// } 44144220746SAlex Crichton /// ``` 44244220746SAlex Crichton pub mod _5_all_world_export_kinds; 44344220746SAlex Crichton 44444220746SAlex Crichton /// Example of a world which exports a resource. 44544220746SAlex Crichton /// 44644220746SAlex Crichton /// * Guest resources are modeled as [`ResourceAny`]. Note that this type is not 44744220746SAlex Crichton /// specialized per-resource at this time so care must be taken to not mix 44844220746SAlex Crichton /// them up. 44944220746SAlex Crichton /// * Resource-related methods are a projection from a [`Guest`] structure, for 45044220746SAlex Crichton /// example to [`GuestLogger`] here. 45144220746SAlex Crichton /// * Resource-related methods all take a [`ResourceAny`] as an argument or 45244220746SAlex Crichton /// a return value. 45344220746SAlex Crichton /// * The [`ResourceAny`] must be explicitly dropped. 45444220746SAlex Crichton /// 45544220746SAlex Crichton /// [`ResourceAny`]: crate::component::ResourceAny 45644220746SAlex Crichton /// [`Guest`]: _6_exported_resources::exports::example::exported_resources::logging::Guest 45744220746SAlex Crichton /// [`GuestLogger`]: _6_exported_resources::exports::example::exported_resources::logging::GuestLogger 45844220746SAlex Crichton /// 45944220746SAlex Crichton /// ```rust 46044220746SAlex Crichton /// use wasmtime::{Result, Engine, Store}; 46144220746SAlex Crichton /// use wasmtime::component::{bindgen, Component, Linker}; 46244220746SAlex Crichton /// use self::exports::example::exported_resources::logging::Level; 46344220746SAlex Crichton /// 46444220746SAlex Crichton #[doc = include_str!("./_6_exported_resources.rs")] 46544220746SAlex Crichton /// 46644220746SAlex Crichton /// struct MyState; 46744220746SAlex Crichton /// 46844220746SAlex Crichton /// fn main() -> Result<()> { 46944220746SAlex Crichton /// # if true { return Ok(()) } 47044220746SAlex Crichton /// let engine = Engine::default(); 47144220746SAlex Crichton /// let component = Component::from_file(&engine, "./your-component.wasm")?; 47244220746SAlex Crichton /// 47344220746SAlex Crichton /// let linker = Linker::new(&engine); 47444220746SAlex Crichton /// // ... this small example has no imports so nothing is added here, but 47544220746SAlex Crichton /// // if you had imports this is where they'd go. 47644220746SAlex Crichton /// 47744220746SAlex Crichton /// let mut store = Store::new(&engine, MyState); 4783171ef6dSAlex Crichton /// let bindings = ExportSomeResources::instantiate(&mut store, &component, &linker)?; 47944220746SAlex Crichton /// let guest = bindings.example_exported_resources_logging(); 48044220746SAlex Crichton /// let logger = guest.logger(); 48144220746SAlex Crichton /// 48244220746SAlex Crichton /// // Resource methods are all attached to `logger` and take the 48344220746SAlex Crichton /// // `ResourceAny` parameter explicitly. 48444220746SAlex Crichton /// let my_logger = logger.call_constructor(&mut store, Level::Warn)?; 48544220746SAlex Crichton /// assert_eq!(logger.call_get_max_level(&mut store, my_logger)?, Level::Warn); 48644220746SAlex Crichton /// logger.call_set_max_level(&mut store, my_logger, Level::Info)?; 48744220746SAlex Crichton /// 48844220746SAlex Crichton /// logger.call_log(&mut store, my_logger, Level::Debug, "hello!")?; 48944220746SAlex Crichton /// 49044220746SAlex Crichton /// // The `ResourceAny` type has no destructor but when the host is done 49144220746SAlex Crichton /// // with it it needs to invoke the guest-level destructor. 49244220746SAlex Crichton /// my_logger.resource_drop(&mut store)?; 49344220746SAlex Crichton /// 49444220746SAlex Crichton /// Ok(()) 49544220746SAlex Crichton /// } 49644220746SAlex Crichton /// ``` 49744220746SAlex Crichton pub mod _6_exported_resources; 498afd8bb39Sifsheldon 499afd8bb39Sifsheldon /// Example of generating **async** bindings for imported resources in a world. 500afd8bb39Sifsheldon /// 501afd8bb39Sifsheldon /// Notable differences from [`_4_imported_resources`] are: 502afd8bb39Sifsheldon /// * async functions are used 503afd8bb39Sifsheldon /// * enabled async in bindgen! macro 504afd8bb39Sifsheldon /// 5059547f2feSHopium /// See [wasi_async_example](https://github.com/bytecodealliance/wasmtime/blob/main/examples/wasip1-async/main.rs) for async function calls on a host. 506afd8bb39Sifsheldon /// 507afd8bb39Sifsheldon /// ```rust 508afd8bb39Sifsheldon /// use wasmtime::Result; 509afd8bb39Sifsheldon /// use wasmtime::component::{bindgen, ResourceTable, Resource}; 510afd8bb39Sifsheldon /// use example::imported_resources::logging::{Level, Host, HostLogger}; 511afd8bb39Sifsheldon /// 512afd8bb39Sifsheldon #[doc = include_str!("./_7_async.rs")] 513afd8bb39Sifsheldon /// 514afd8bb39Sifsheldon /// #[derive(Default)] 515afd8bb39Sifsheldon /// struct MyState { 516afd8bb39Sifsheldon /// // Manages the mapping of `MyLogger` structures to `Resource<MyLogger>`. 517afd8bb39Sifsheldon /// table: ResourceTable, 518afd8bb39Sifsheldon /// } 519afd8bb39Sifsheldon /// 520afd8bb39Sifsheldon /// // There are no free-functions on `interface logging`, so this is an empty 521afd8bb39Sifsheldon /// // impl. 522afd8bb39Sifsheldon /// impl Host for MyState {} 523afd8bb39Sifsheldon /// 524afd8bb39Sifsheldon /// // This separate `HostLogger` trait serves to act as a namespace for just 525afd8bb39Sifsheldon /// // the `logger`-related resource methods. 526afd8bb39Sifsheldon /// impl HostLogger for MyState { 527afd8bb39Sifsheldon /// // A `constructor` in WIT maps to a `new` function in Rust. 528afd8bb39Sifsheldon /// async fn new(&mut self, max_level: Level) -> Result<Resource<MyLogger>> { 529afd8bb39Sifsheldon /// let id = self.table.push(MyLogger { max_level })?; 530afd8bb39Sifsheldon /// Ok(id) 531afd8bb39Sifsheldon /// } 532afd8bb39Sifsheldon /// 533afd8bb39Sifsheldon /// async fn get_max_level(&mut self, logger: Resource<MyLogger>) -> Result<Level> { 534afd8bb39Sifsheldon /// debug_assert!(!logger.owned()); 535afd8bb39Sifsheldon /// let logger = self.table.get(&logger)?; 536afd8bb39Sifsheldon /// Ok(logger.max_level) 537afd8bb39Sifsheldon /// } 538afd8bb39Sifsheldon /// 539afd8bb39Sifsheldon /// async fn set_max_level(&mut self, logger: Resource<MyLogger>, level: Level) -> Result<()> { 540afd8bb39Sifsheldon /// debug_assert!(!logger.owned()); 541afd8bb39Sifsheldon /// let logger = self.table.get_mut(&logger)?; 542afd8bb39Sifsheldon /// logger.max_level = level; 543afd8bb39Sifsheldon /// Ok(()) 544afd8bb39Sifsheldon /// } 545afd8bb39Sifsheldon /// 546afd8bb39Sifsheldon /// async fn log(&mut self, logger: Resource<MyLogger>, level: Level, msg: String) -> Result<()> { 547afd8bb39Sifsheldon /// debug_assert!(!logger.owned()); 548afd8bb39Sifsheldon /// let logger = self.table.get_mut(&logger)?; 549afd8bb39Sifsheldon /// if (level as u32) <= (logger.max_level as u32) { 550afd8bb39Sifsheldon /// println!("{msg}"); 551afd8bb39Sifsheldon /// } 552afd8bb39Sifsheldon /// Ok(()) 553afd8bb39Sifsheldon /// } 554afd8bb39Sifsheldon /// 555afd8bb39Sifsheldon /// async fn drop(&mut self, logger: Resource<MyLogger>) -> Result<()> { 556afd8bb39Sifsheldon /// debug_assert!(logger.owned()); 557afd8bb39Sifsheldon /// let _logger: MyLogger = self.table.delete(logger)?; 558afd8bb39Sifsheldon /// // ... custom destruction logic here if necessary, otherwise 559afd8bb39Sifsheldon /// // a `Drop for MyLogger` would also work. 560afd8bb39Sifsheldon /// Ok(()) 561afd8bb39Sifsheldon /// } 562afd8bb39Sifsheldon /// } 563afd8bb39Sifsheldon /// 564afd8bb39Sifsheldon /// # fn main() {} 565afd8bb39Sifsheldon /// ``` 566afd8bb39Sifsheldon pub mod _7_async; 567*9f47be2eSAlex Crichton 568*9f47be2eSAlex Crichton /// Example of using [`StoreContextMut`] in imported functions. 569*9f47be2eSAlex Crichton /// 570*9f47be2eSAlex Crichton /// This is an example of using the `store` option to the `imports` 571*9f47be2eSAlex Crichton /// configuration of the [`bindgen!`](crate::component::bindgen) macro. Like 572*9f47be2eSAlex Crichton /// seen in previous examples a 573*9f47be2eSAlex Crichton /// [`MyWorldImports`](_8_store_in_imports::MyWorldImports) trait is generated 574*9f47be2eSAlex Crichton /// for `my-world`, but imports that have access to the store get added to a 575*9f47be2eSAlex Crichton /// separate trait with a `*WithStore` suffix, in this case 576*9f47be2eSAlex Crichton /// [`MyWorldImportsWithStore`](_8_store_in_imports::MyWorldImportsWithStore). 577*9f47be2eSAlex Crichton /// This second trait provides access to a [`StoreContextMut`]. 578*9f47be2eSAlex Crichton /// 579*9f47be2eSAlex Crichton /// [`StoreContextMut`]: crate::StoreContextMut 580*9f47be2eSAlex Crichton /// 581*9f47be2eSAlex Crichton /// ```rust 582*9f47be2eSAlex Crichton /// use wasmtime::component::{bindgen, HasData, Access, Accessor}; 583*9f47be2eSAlex Crichton /// use wasmtime::{StoreContextMut, AsContextMut}; 584*9f47be2eSAlex Crichton /// 585*9f47be2eSAlex Crichton #[doc = include_str!("./_8_store_in_imports.rs")] 586*9f47be2eSAlex Crichton /// 587*9f47be2eSAlex Crichton /// struct MyState { 588*9f47be2eSAlex Crichton /// // ... 589*9f47be2eSAlex Crichton /// } 590*9f47be2eSAlex Crichton /// 591*9f47be2eSAlex Crichton /// impl HasData for MyState { 592*9f47be2eSAlex Crichton /// type Data<'a> = &'a mut MyState; 593*9f47be2eSAlex Crichton /// } 594*9f47be2eSAlex Crichton /// 595*9f47be2eSAlex Crichton /// impl MyWorldImportsWithStore for MyState { 596*9f47be2eSAlex Crichton /// /// Synchronous functions that have access to the store are defined in 597*9f47be2eSAlex Crichton /// /// Rust as a normal `fn` with an `Access` as the first parameter. 598*9f47be2eSAlex Crichton /// fn sync_with_store<T>(mut host: Access<'_, T, Self>) { 599*9f47be2eSAlex Crichton /// // The `Access` type implements `AsContextMut` to manipulate and 600*9f47be2eSAlex Crichton /// // operate on the store. 601*9f47be2eSAlex Crichton /// let mut store: StoreContextMut<'_, T> = host.as_context_mut(); 602*9f47be2eSAlex Crichton /// 603*9f47be2eSAlex Crichton /// // The `Access` type can be used to get the `Data` projection of 604*9f47be2eSAlex Crichton /// // the `HasData` trait implementation above, in this case 605*9f47be2eSAlex Crichton /// // ourselves. 606*9f47be2eSAlex Crichton /// let my_state: &mut MyState = host.get(); 607*9f47be2eSAlex Crichton /// } 608*9f47be2eSAlex Crichton /// 609*9f47be2eSAlex Crichton /// /// Asynchronous functions that have access to the store are defined in 610*9f47be2eSAlex Crichton /// /// Rust as an `async fn` with an `Accessor` as the first parameter. 611*9f47be2eSAlex Crichton /// async fn async_with_store<T>(accessor: &Accessor<T, Self>) { 612*9f47be2eSAlex Crichton /// // The `Accessor` type does not implement `AsContextMut` directly 613*9f47be2eSAlex Crichton /// // and instead represents the ability to, synchronously, work with 614*9f47be2eSAlex Crichton /// // the store. Notably borrows into the store or `Self` cannot be 615*9f47be2eSAlex Crichton /// // persisted across await points 616*9f47be2eSAlex Crichton /// accessor.with(|mut access| { 617*9f47be2eSAlex Crichton /// // same as `sync_with_store` above 618*9f47be2eSAlex Crichton /// let mut store: StoreContextMut<'_, T> = access.as_context_mut(); 619*9f47be2eSAlex Crichton /// let my_state: &mut MyState = access.get(); 620*9f47be2eSAlex Crichton /// 621*9f47be2eSAlex Crichton /// // ... 622*9f47be2eSAlex Crichton /// }); 623*9f47be2eSAlex Crichton /// 624*9f47be2eSAlex Crichton /// some_function().await; 625*9f47be2eSAlex Crichton /// # async fn some_function() {} 626*9f47be2eSAlex Crichton /// 627*9f47be2eSAlex Crichton /// accessor.with(|mut access| { 628*9f47be2eSAlex Crichton /// // ... 629*9f47be2eSAlex Crichton /// }); 630*9f47be2eSAlex Crichton /// } 631*9f47be2eSAlex Crichton /// } 632*9f47be2eSAlex Crichton /// 633*9f47be2eSAlex Crichton /// // Functions that don't have access to the store are defined with 634*9f47be2eSAlex Crichton /// // `&mut self` indicating that they can only access data in `self`, not the 635*9f47be2eSAlex Crichton /// // entire store. 636*9f47be2eSAlex Crichton /// impl MyWorldImports for MyState { 637*9f47be2eSAlex Crichton /// fn sync_without_store(&mut self) { /* ... */ } 638*9f47be2eSAlex Crichton /// async fn async_without_store(&mut self) { /* ... */ } 639*9f47be2eSAlex Crichton /// } 640*9f47be2eSAlex Crichton /// 641*9f47be2eSAlex Crichton /// # fn main() {} 642*9f47be2eSAlex Crichton /// ``` 643*9f47be2eSAlex Crichton #[cfg(feature = "component-model-async")] 644*9f47be2eSAlex Crichton pub mod _8_store_in_imports; 645