1 //! Examples of output of the [`bindgen!`] macro. 2 //! 3 //! This module is only included in docs.rs documentation and is not present in 4 //! the actual crate when compiling from crates.io. The purpose of this module 5 //! is to showcase what the output of the [`bindgen!`] macro looks like and some 6 //! examples of how to use it. 7 //! 8 //! If you're confused or lost in [`bindgen!`] feel free to [open an issue] 9 //! with a description of your issue and it can hopefully lead to a new example 10 //! being added here for others to use as reference. 11 //! 12 //! ## Including `*.wit` files in your project 13 //! 14 //! Note that most of the examples in this module will use the `inline` key of 15 //! the [`bindgen!`] macro. This is done as it's easy to show the example and 16 //! WIT all in one self-contained snippet of Rust code. Typically though a 17 //! project will have a `wit` directory next to `Cargo.toml` which contains WIT 18 //! files. 19 //! 20 //! The general layout of a `wit` directory is that: 21 //! 22 //! * All `*.wit` files at `wit/*.wit` are parsed and included in the same 23 //! package. 24 //! * If the `wit/deps` folder is present then it can either contain: 25 //! * Subdirectories with a package-per-directory. For example 26 //! `wit/deps/wasi-http` and `wit/deps/wasi-cli`. 27 //! * WIT files that are a single-file rendering of a package, for example 28 //! `wit/deps/wasi-http.wit` 29 //! * WIT packages encoded as WebAssembly binaries for a package, for example 30 //! `wit/deps/wasi-http.wasm` 31 //! 32 //! This means that at this time you'll need to copy around `*.wit` files or 33 //! WIT packages encoded as `*.wasm` and check them in to your project's `wit` 34 //! directory. The hope is that in the future it will be easier to manage these 35 //! files with registry tooling and they won't have to be copied manually. 36 //! For reference documentation on the layout of the `wit` directory see 37 //! [`wit_parser::Resolve::push_dir`]. 38 //! 39 //! [`bindgen!`]: crate::component::bindgen 40 //! [`wit_parser::Resolve::push_dir`]: https://docs.rs/wit-parser/latest/wit_parser/struct.Resolve.html#method.push_dir 41 //! [open an issue]: https://github.com/bytecodealliance/wasmtime/issues/new 42 43 #![allow(missing_docs)] 44 45 // This "hack" will shadow the `bindgen` macro in general and be inherited to 46 // following modules by default. This enables documenting sources as-is while 47 // additionally customizing them to working within the wasmtime crate itself by 48 // injecting a configuration option to change how the `wasmtime` crate is 49 // referenced in the generated output. 50 // 51 // Note that this has an additional "hack" such that when docs.rs is documenting 52 // this crate (or CI) then `include_generated_code_from_file` is unconditionally 53 // turned on. This makes `[source]` links on documentation show the actual 54 // generated code rather than just the `bindgen!` macro invocation, which can be 55 // helpful when exploring code. 56 #[cfg(docsrs)] 57 macro_rules! bindgen { 58 ({$($t:tt)*}) => (crate::component::bindgen!({ 59 $($t)* 60 wasmtime_crate: crate, 61 include_generated_code_from_file: true, 62 });); 63 } 64 #[cfg(not(docsrs))] 65 macro_rules! bindgen { 66 ({$($t:tt)*}) => (crate::component::bindgen!({ 67 $($t)* 68 wasmtime_crate: crate, 69 });); 70 } 71 72 /// A "hello world" style example. 73 /// 74 /// This example loads a component which has access to a single host function. 75 /// The exported function is called on an instantiation of the component. 76 /// 77 /// ```rust 78 /// use wasmtime::component::*; 79 /// use wasmtime::{Engine, Store}; 80 /// 81 #[doc = include_str!("./_0_hello_world.rs")] 82 /// 83 /// struct MyState { 84 /// name: String, 85 /// } 86 /// 87 /// // Imports into the world, like the `name` import for this world, are 88 /// // satisfied through traits. 89 /// impl HelloWorldImports for MyState { 90 /// fn name(&mut self) -> String { 91 /// self.name.clone() 92 /// } 93 /// } 94 /// 95 /// fn main() -> wasmtime::Result<()> { 96 /// # if true { return Ok(()) } 97 /// // Compile the `Component` that is being run for the application. 98 /// let engine = Engine::default(); 99 /// let component = Component::from_file(&engine, "./your-component.wasm")?; 100 /// 101 /// // Instantiation of bindings always happens through a `Linker`. 102 /// // Configuration of the linker is done through a generated `add_to_linker` 103 /// // method on the bindings structure. 104 /// // 105 /// // Note that the function provided here is a projection from `T` in 106 /// // `Store<T>` to `&mut U` where `U` implements the `HelloWorldImports` 107 /// // trait. In this case the `T`, `MyState`, is stored directly in the 108 /// // structure so no projection is necessary here. 109 /// // 110 /// // Note that the second type parameter of `add_to_linker` is chosen here 111 /// // as the built-in `HasSelf` type in Wasmtime. This effectively says 112 /// // that our function isn't actually projecting, it's returning the 113 /// // input, so `HasSelf<_>` is a convenience to avoid writing a custom 114 /// // `HasData` implementation. 115 /// let mut linker = Linker::new(&engine); 116 /// HelloWorld::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 117 /// 118 /// // As with the core wasm API of Wasmtime instantiation occurs within a 119 /// // `Store`. The bindings structure contains an `instantiate` method which 120 /// // takes the store, component, and linker. This returns the `bindings` 121 /// // structure which is an instance of `HelloWorld` and supports typed access 122 /// // to the exports of the component. 123 /// let mut store = Store::new( 124 /// &engine, 125 /// MyState { 126 /// name: "me".to_string(), 127 /// }, 128 /// ); 129 /// let bindings = HelloWorld::instantiate(&mut store, &component, &linker)?; 130 /// 131 /// // Here our `greet` function doesn't take any parameters for the component, 132 /// // but in the Wasmtime embedding API the first argument is always a `Store`. 133 /// bindings.call_greet(&mut store)?; 134 /// Ok(()) 135 /// } 136 /// ``` 137 pub mod _0_hello_world; 138 139 /// An example of generated bindings for top-level imported functions and 140 /// interfaces into a world. 141 /// 142 /// The code used to generate this module is: 143 /// 144 /// ```rust 145 /// use wasmtime::component::*; 146 /// use wasmtime::{Engine, Store}; 147 /// 148 #[doc = include_str!("./_1_world_imports.rs")] 149 /// 150 /// struct MyState { 151 /// // ... 152 /// } 153 /// 154 /// impl my_custom_host::Host for MyState { 155 /// fn tick(&mut self) { 156 /// todo!() 157 /// } 158 /// } 159 /// 160 /// impl MyWorldImports for MyState { 161 /// fn greet(&mut self) -> String { 162 /// todo!() 163 /// } 164 /// 165 /// fn log(&mut self, msg: String) { 166 /// println!("{msg}"); 167 /// } 168 /// } 169 /// 170 /// fn main() -> wasmtime::Result<()> { 171 /// # if true { return Ok(()) } 172 /// let engine = Engine::default(); 173 /// let component = Component::from_file(&engine, "./your-component.wasm")?; 174 /// 175 /// let mut linker = Linker::new(&engine); 176 /// MyWorld::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 177 /// 178 /// let mut store = Store::new( 179 /// &engine, 180 /// MyState { /* ... */ }, 181 /// ); 182 /// let bindings = MyWorld::instantiate(&mut store, &component, &linker)?; 183 /// 184 /// // ... NB: this world has no exports just yet so not much can be done 185 /// // with `bindings`. 186 /// 187 /// Ok(()) 188 /// } 189 /// ``` 190 pub mod _1_world_imports; 191 192 /// An example of generated bindings for top-level exported functions for a 193 /// world. 194 /// 195 /// Some notable generated items here are: 196 /// 197 /// * [`my::project::host::Host`](_2_world_exports::my::project::host::Host) - 198 /// the generated trait for the `interface host` import. 199 /// * [`exports::demo::Guest`](_2_world_exports::exports::demo::Guest) - 200 /// the generated structured used to invoke exports on the returned instance. 201 /// * [`HelloWorld`](_2_world_exports::HelloWorld) - 202 /// the overall generated structure representing our `world`. 203 /// 204 /// ```rust 205 /// use wasmtime::component::*; 206 /// use wasmtime::{Engine, Store}; 207 /// 208 #[doc = include_str!("./_2_world_exports.rs")] 209 /// 210 /// struct MyState { 211 /// // ... 212 /// } 213 /// 214 /// # mod rand { pub fn thread_rng() -> G { G } pub struct G; impl G { pub fn r#gen(&self) -> u32 { 0 } } } 215 /// // Note that the trait here is per-interface and within a submodule now. 216 /// impl my::project::host::Host for MyState { 217 /// fn gen_random_integer(&mut self) -> u32 { 218 /// rand::thread_rng().r#gen() 219 /// } 220 /// 221 /// fn sha256(&mut self, bytes: Vec<u8>) -> String { 222 /// // ... 223 /// # panic!() 224 /// } 225 /// } 226 /// 227 /// fn main() -> wasmtime::Result<()> { 228 /// # if true { return Ok(()) } 229 /// let engine = Engine::default(); 230 /// let component = Component::from_file(&engine, "./your-component.wasm")?; 231 /// 232 /// let mut linker = Linker::new(&engine); 233 /// HelloWorld::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 234 /// 235 /// let mut store = Store::new( 236 /// &engine, 237 /// MyState { /* ... */ }, 238 /// ); 239 /// let bindings = HelloWorld::instantiate(&mut store, &component, &linker)?; 240 /// 241 /// // Note that the `demo` method returns a `&exports::Demo::Guest` 242 /// // through which we can run the methods on that interface. 243 /// bindings.demo().call_run(&mut store)?; 244 /// Ok(()) 245 /// } 246 /// ``` 247 pub mod _2_world_exports; 248 249 /// Example of generating bindings for imported interfaces in a world. 250 /// 251 /// Notable parts of this example are: 252 /// 253 /// * Imported interfaces use the Rust module system to encapsulate themselves. 254 /// The interface imported here is `example:interface-imports/logging` so the 255 /// generated trait and types are located in 256 /// [`example::interface_imports::logging`][module]. 257 /// * Types in the `logging` interface are generated in the `logging` module, 258 /// for example [`Level`]. 259 /// * Generated types have implementations of [`ComponentType`], [`Lift`], and 260 /// [`Lower`] derived. 261 /// * The generated trait that host's must implement is always called [`Host`] 262 /// and is located in the generated module. 263 /// 264 /// [module]: _3_interface_imports::example::interface_imports::logging 265 /// [`Level`]: _3_interface_imports::example::interface_imports::logging::Level 266 /// [`Host`]: _3_interface_imports::example::interface_imports::logging::Host 267 /// [`ComponentType`]: crate::component::ComponentType 268 /// [`Lift`]: crate::component::Lift 269 /// [`Lower`]: crate::component::Lower 270 /// 271 /// ```rust 272 /// use wasmtime::component::bindgen; 273 /// use example::interface_imports::logging::Level; 274 /// 275 #[doc = include_str!("./_3_interface_imports.rs")] 276 /// 277 /// struct MyState { 278 /// // ... 279 /// } 280 /// 281 /// impl example::interface_imports::logging::Host for MyState { 282 /// fn log(&mut self, level: Level, msg: String) { 283 /// // ... 284 /// } 285 /// } 286 /// ``` 287 pub mod _3_interface_imports; 288 289 /// Example of generating bindings for imported resources in a world. 290 /// 291 /// Notable parts of this example are: 292 /// 293 /// * Imported resources from the host are represented as traits, in this case 294 /// [`HostLogger`]. 295 /// * The per-interface [`Host`] trait still exists but has a supertrait of 296 /// [`HostLogger`]. 297 /// * Resources are represented as [`Resource<T>`] and it's recommended to 298 /// specify a `with` key to indicate what host type you'd like to use for 299 /// each resource. 300 /// * A [`ResourceTable`] can be used to manage resources when working with 301 /// guests. 302 /// 303 /// [`Host`]: _4_imported_resources::example::imported_resources::logging::Host 304 /// [`HostLogger`]: _4_imported_resources::example::imported_resources::logging::HostLogger 305 /// [`Resource<T>`]: crate::component::Resource 306 /// [`ResourceTable`]: crate::component::ResourceTable 307 /// 308 /// ```rust 309 /// use wasmtime::Result; 310 /// use wasmtime::component::{bindgen, ResourceTable, Resource}; 311 /// use example::imported_resources::logging::{Level, Host, HostLogger}; 312 /// 313 #[doc = include_str!("./_4_imported_resources.rs")] 314 /// 315 /// #[derive(Default)] 316 /// struct MyState { 317 /// // Manages the mapping of `MyLogger` structures to `Resource<MyLogger>`. 318 /// table: ResourceTable, 319 /// } 320 /// 321 /// // There are no free-functions on `interface logging`, so this is an empty 322 /// // impl. 323 /// impl Host for MyState {} 324 /// 325 /// // This separate `HostLogger` trait serves to act as a namespace for just 326 /// // the `logger`-related resource methods. 327 /// impl HostLogger for MyState { 328 /// // A `constructor` in WIT maps to a `new` function in Rust. 329 /// fn new(&mut self, max_level: Level) -> Result<Resource<MyLogger>> { 330 /// let id = self.table.push(MyLogger { max_level })?; 331 /// Ok(id) 332 /// } 333 /// 334 /// fn get_max_level(&mut self, logger: Resource<MyLogger>) -> Result<Level> { 335 /// debug_assert!(!logger.owned()); 336 /// let logger = self.table.get(&logger)?; 337 /// Ok(logger.max_level) 338 /// } 339 /// 340 /// fn set_max_level(&mut self, logger: Resource<MyLogger>, level: Level) -> Result<()> { 341 /// debug_assert!(!logger.owned()); 342 /// let logger = self.table.get_mut(&logger)?; 343 /// logger.max_level = level; 344 /// Ok(()) 345 /// } 346 /// 347 /// fn log(&mut self, logger: Resource<MyLogger>, level: Level, msg: String) -> Result<()> { 348 /// debug_assert!(!logger.owned()); 349 /// let logger = self.table.get_mut(&logger)?; 350 /// if (level as u32) <= (logger.max_level as u32) { 351 /// println!("{msg}"); 352 /// } 353 /// Ok(()) 354 /// } 355 /// 356 /// fn drop(&mut self, logger: Resource<MyLogger>) -> Result<()> { 357 /// debug_assert!(logger.owned()); 358 /// let _logger: MyLogger = self.table.delete(logger)?; 359 /// // ... custom destruction logic here if necessary, otherwise 360 /// // a `Drop for MyLogger` would also work. 361 /// Ok(()) 362 /// } 363 /// } 364 /// 365 /// # fn main() {} 366 /// ``` 367 pub mod _4_imported_resources; 368 369 /// Example of all kinds of structures of exports from a world. 370 /// 371 /// * Top-level functions in a `world` are exported directly on the generated 372 /// structure such as [`call_run`]. 373 /// * All other exports are otherwise scoped with generated traits/types 374 /// in a top level [`exports`] module. 375 /// * Exported named interfaces are located at the root of the [`exports`] 376 /// module, such as [`exports::environment`]. 377 /// * Interfaces are all bound with a structure called `Guest` which has typed 378 /// functions for each export that can be called. For example 379 /// [`exports::environment::Guest`][guest1] and 380 /// [`exports::example::world_exports::units::Guest`][guest2]. 381 /// * Interfaces exported by their id are modeled with multiple namespacing 382 /// modules, such as [`exports::example::world_exports::units`][units]. 383 /// 384 /// [`call_run`]: _5_all_world_export_kinds::WithExports::call_run 385 /// [`exports`]: _5_all_world_export_kinds::exports 386 /// [`exports::environment`]: _5_all_world_export_kinds::exports::environment 387 /// [guest1]: _5_all_world_export_kinds::exports::environment::Guest 388 /// [guest2]: _5_all_world_export_kinds::exports::example::world_exports::units::Guest 389 /// [units]: _5_all_world_export_kinds::exports::example::world_exports::units 390 /// 391 /// ```rust 392 /// use wasmtime::{Result, Engine, Store}; 393 /// use wasmtime::component::{bindgen, Component, Linker, HasSelf}; 394 /// 395 #[doc = include_str!("./_5_all_world_export_kinds.rs")] 396 /// 397 /// struct MyState; 398 /// 399 /// impl WithExportsImports for MyState { 400 /// fn log(&mut self, msg: String) { 401 /// println!("{msg}"); 402 /// } 403 /// } 404 /// 405 /// fn main() -> Result<()> { 406 /// # if true { return Ok(()) } 407 /// let engine = Engine::default(); 408 /// let component = Component::from_file(&engine, "./your-component.wasm")?; 409 /// 410 /// let mut linker = Linker::new(&engine); 411 /// WithExports::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 412 /// 413 /// let mut store = Store::new(&engine, MyState); 414 /// let bindings = WithExports::instantiate(&mut store, &component, &linker)?; 415 /// 416 /// // top-level functions are exported directly on `WithExports` and are 417 /// // all prefixed with `call_*`. 418 /// bindings.call_run(&mut store)?; 419 /// 420 /// // exported named interfaces are named directly after their export name 421 /// // and the `&Guest` return value has `call_*` functions on it. 422 /// bindings.environment().call_set(&mut store, "key", "value")?; 423 /// let value = bindings.environment().call_get(&mut store, "key")?; 424 /// assert_eq!(value, "value"); 425 /// 426 /// // exported interfaces by id are similar to export-by-name except that 427 /// // the exported name is modeled after the full id, not just the name. 428 /// let units = bindings.example_world_exports_units(); 429 /// let bytes = 1 << 30 + 1 << 20; 430 /// let s = units.call_bytes_to_string(&mut store, bytes)?; 431 /// println!("{bytes} = {s}"); 432 /// 433 /// let (seconds, ns) = (1 << 20, 12345); 434 /// let s = units.call_duration_to_string(&mut store, seconds, ns)?; 435 /// println!("{seconds}s + {ns}ns = {s}"); 436 /// Ok(()) 437 /// } 438 /// ``` 439 pub mod _5_all_world_export_kinds; 440 441 /// Example of a world which exports a resource. 442 /// 443 /// * Guest resources are modeled as [`ResourceAny`]. Note that this type is not 444 /// specialized per-resource at this time so care must be taken to not mix 445 /// them up. 446 /// * Resource-related methods are a projection from a [`Guest`] structure, for 447 /// example to [`GuestLogger`] here. 448 /// * Resource-related methods all take a [`ResourceAny`] as an argument or 449 /// a return value. 450 /// * The [`ResourceAny`] must be explicitly dropped. 451 /// 452 /// [`ResourceAny`]: crate::component::ResourceAny 453 /// [`Guest`]: _6_exported_resources::exports::example::exported_resources::logging::Guest 454 /// [`GuestLogger`]: _6_exported_resources::exports::example::exported_resources::logging::GuestLogger 455 /// 456 /// ```rust 457 /// use wasmtime::{Result, Engine, Store}; 458 /// use wasmtime::component::{bindgen, Component, Linker}; 459 /// use self::exports::example::exported_resources::logging::Level; 460 /// 461 #[doc = include_str!("./_6_exported_resources.rs")] 462 /// 463 /// struct MyState; 464 /// 465 /// fn main() -> Result<()> { 466 /// # if true { return Ok(()) } 467 /// let engine = Engine::default(); 468 /// let component = Component::from_file(&engine, "./your-component.wasm")?; 469 /// 470 /// let linker = Linker::new(&engine); 471 /// // ... this small example has no imports so nothing is added here, but 472 /// // if you had imports this is where they'd go. 473 /// 474 /// let mut store = Store::new(&engine, MyState); 475 /// let bindings = ExportSomeResources::instantiate(&mut store, &component, &linker)?; 476 /// let guest = bindings.example_exported_resources_logging(); 477 /// let logger = guest.logger(); 478 /// 479 /// // Resource methods are all attached to `logger` and take the 480 /// // `ResourceAny` parameter explicitly. 481 /// let my_logger = logger.call_constructor(&mut store, Level::Warn)?; 482 /// assert_eq!(logger.call_get_max_level(&mut store, my_logger)?, Level::Warn); 483 /// logger.call_set_max_level(&mut store, my_logger, Level::Info)?; 484 /// 485 /// logger.call_log(&mut store, my_logger, Level::Debug, "hello!")?; 486 /// 487 /// // The `ResourceAny` type has no destructor but when the host is done 488 /// // with it it needs to invoke the guest-level destructor. 489 /// my_logger.resource_drop(&mut store)?; 490 /// 491 /// Ok(()) 492 /// } 493 /// ``` 494 pub mod _6_exported_resources; 495 496 /// Example of generating **async** bindings for imported resources in a world. 497 /// 498 /// Notable differences from [`_4_imported_resources`] are: 499 /// * async functions are used 500 /// * enabled async in bindgen! macro 501 /// 502 /// See [wasi_async_example](https://github.com/bytecodealliance/wasmtime/blob/main/examples/wasip1-async/main.rs) for async function calls on a host. 503 /// 504 /// ```rust 505 /// use wasmtime::Result; 506 /// use wasmtime::component::{bindgen, ResourceTable, Resource}; 507 /// use example::imported_resources::logging::{Level, Host, HostLogger}; 508 /// 509 #[doc = include_str!("./_7_async.rs")] 510 /// 511 /// #[derive(Default)] 512 /// struct MyState { 513 /// // Manages the mapping of `MyLogger` structures to `Resource<MyLogger>`. 514 /// table: ResourceTable, 515 /// } 516 /// 517 /// // There are no free-functions on `interface logging`, so this is an empty 518 /// // impl. 519 /// impl Host for MyState {} 520 /// 521 /// // This separate `HostLogger` trait serves to act as a namespace for just 522 /// // the `logger`-related resource methods. 523 /// impl HostLogger for MyState { 524 /// // A `constructor` in WIT maps to a `new` function in Rust. 525 /// async fn new(&mut self, max_level: Level) -> Result<Resource<MyLogger>> { 526 /// let id = self.table.push(MyLogger { max_level })?; 527 /// Ok(id) 528 /// } 529 /// 530 /// async fn get_max_level(&mut self, logger: Resource<MyLogger>) -> Result<Level> { 531 /// debug_assert!(!logger.owned()); 532 /// let logger = self.table.get(&logger)?; 533 /// Ok(logger.max_level) 534 /// } 535 /// 536 /// async fn set_max_level(&mut self, logger: Resource<MyLogger>, level: Level) -> Result<()> { 537 /// debug_assert!(!logger.owned()); 538 /// let logger = self.table.get_mut(&logger)?; 539 /// logger.max_level = level; 540 /// Ok(()) 541 /// } 542 /// 543 /// async fn log(&mut self, logger: Resource<MyLogger>, level: Level, msg: String) -> Result<()> { 544 /// debug_assert!(!logger.owned()); 545 /// let logger = self.table.get_mut(&logger)?; 546 /// if (level as u32) <= (logger.max_level as u32) { 547 /// println!("{msg}"); 548 /// } 549 /// Ok(()) 550 /// } 551 /// 552 /// async fn drop(&mut self, logger: Resource<MyLogger>) -> Result<()> { 553 /// debug_assert!(logger.owned()); 554 /// let _logger: MyLogger = self.table.delete(logger)?; 555 /// // ... custom destruction logic here if necessary, otherwise 556 /// // a `Drop for MyLogger` would also work. 557 /// Ok(()) 558 /// } 559 /// } 560 /// 561 /// # fn main() {} 562 /// ``` 563 pub mod _7_async; 564