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 #![expect( 44 missing_docs, 45 reason = "bindgen-generated types known to not have docs" 46 )] 47 48 // This "hack" will shadow the `bindgen` macro in general and be inherited to 49 // following modules by default. This enables documenting sources as-is while 50 // additionally customizing them to working within the wasmtime crate itself by 51 // injecting a configuration option to change how the `wasmtime` crate is 52 // referenced in the generated output. 53 // 54 // Note that this has an additional "hack" such that when docs.rs is documenting 55 // this crate (or CI) then `include_generated_code_from_file` is unconditionally 56 // turned on. This makes `[source]` links on documentation show the actual 57 // generated code rather than just the `bindgen!` macro invocation, which can be 58 // helpful when exploring code. 59 #[cfg(docsrs)] 60 macro_rules! bindgen { 61 ({$($t:tt)*}) => (crate::component::bindgen!({ 62 $($t)* 63 wasmtime_crate: crate, 64 include_generated_code_from_file: true, 65 });); 66 } 67 #[cfg(not(docsrs))] 68 macro_rules! bindgen { 69 ({$($t:tt)*}) => (crate::component::bindgen!({ 70 $($t)* 71 wasmtime_crate: crate, 72 });); 73 } 74 75 /// A "hello world" style example. 76 /// 77 /// This example loads a component which has access to a single host function. 78 /// The exported function is called on an instantiation of the component. 79 /// 80 /// ```rust 81 /// use wasmtime::component::*; 82 /// use wasmtime::{Engine, Store}; 83 /// 84 #[doc = include_str!("./_0_hello_world.rs")] 85 /// 86 /// struct MyState { 87 /// name: String, 88 /// } 89 /// 90 /// // Imports into the world, like the `name` import for this world, are 91 /// // satisfied through traits. 92 /// impl HelloWorldImports for MyState { 93 /// fn name(&mut self) -> String { 94 /// self.name.clone() 95 /// } 96 /// } 97 /// 98 /// fn main() -> wasmtime::Result<()> { 99 /// # if true { return Ok(()) } 100 /// // Compile the `Component` that is being run for the application. 101 /// let engine = Engine::default(); 102 /// let component = Component::from_file(&engine, "./your-component.wasm")?; 103 /// 104 /// // Instantiation of bindings always happens through a `Linker`. 105 /// // Configuration of the linker is done through a generated `add_to_linker` 106 /// // method on the bindings structure. 107 /// // 108 /// // Note that the function provided here is a projection from `T` in 109 /// // `Store<T>` to `&mut U` where `U` implements the `HelloWorldImports` 110 /// // trait. In this case the `T`, `MyState`, is stored directly in the 111 /// // structure so no projection is necessary here. 112 /// // 113 /// // Note that the second type parameter of `add_to_linker` is chosen here 114 /// // as the built-in `HasSelf` type in Wasmtime. This effectively says 115 /// // that our function isn't actually projecting, it's returning the 116 /// // input, so `HasSelf<_>` is a convenience to avoid writing a custom 117 /// // `HasData` implementation. 118 /// let mut linker = Linker::new(&engine); 119 /// HelloWorld::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 120 /// 121 /// // As with the core wasm API of Wasmtime instantiation occurs within a 122 /// // `Store`. The bindings structure contains an `instantiate` method which 123 /// // takes the store, component, and linker. This returns the `bindings` 124 /// // structure which is an instance of `HelloWorld` and supports typed access 125 /// // to the exports of the component. 126 /// let mut store = Store::new( 127 /// &engine, 128 /// MyState { 129 /// name: "me".to_string(), 130 /// }, 131 /// ); 132 /// let bindings = HelloWorld::instantiate(&mut store, &component, &linker)?; 133 /// 134 /// // Here our `greet` function doesn't take any parameters for the component, 135 /// // but in the Wasmtime embedding API the first argument is always a `Store`. 136 /// bindings.call_greet(&mut store)?; 137 /// Ok(()) 138 /// } 139 /// ``` 140 pub mod _0_hello_world; 141 142 /// An example of generated bindings for top-level imported functions and 143 /// interfaces into a world. 144 /// 145 /// The code used to generate this module is: 146 /// 147 /// ```rust 148 /// use wasmtime::component::*; 149 /// use wasmtime::{Engine, Store}; 150 /// 151 #[doc = include_str!("./_1_world_imports.rs")] 152 /// 153 /// struct MyState { 154 /// // ... 155 /// } 156 /// 157 /// impl my_custom_host::Host for MyState { 158 /// fn tick(&mut self) { 159 /// todo!() 160 /// } 161 /// } 162 /// 163 /// impl MyWorldImports for MyState { 164 /// fn greet(&mut self) -> String { 165 /// todo!() 166 /// } 167 /// 168 /// fn log(&mut self, msg: String) { 169 /// println!("{msg}"); 170 /// } 171 /// } 172 /// 173 /// fn main() -> wasmtime::Result<()> { 174 /// # if true { return Ok(()) } 175 /// let engine = Engine::default(); 176 /// let component = Component::from_file(&engine, "./your-component.wasm")?; 177 /// 178 /// let mut linker = Linker::new(&engine); 179 /// MyWorld::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 180 /// 181 /// let mut store = Store::new( 182 /// &engine, 183 /// MyState { /* ... */ }, 184 /// ); 185 /// let bindings = MyWorld::instantiate(&mut store, &component, &linker)?; 186 /// 187 /// // ... NB: this world has no exports just yet so not much can be done 188 /// // with `bindings`. 189 /// 190 /// Ok(()) 191 /// } 192 /// ``` 193 pub mod _1_world_imports; 194 195 /// An example of generated bindings for top-level exported functions for a 196 /// world. 197 /// 198 /// Some notable generated items here are: 199 /// 200 /// * [`my::project::host::Host`](_2_world_exports::my::project::host::Host) - 201 /// the generated trait for the `interface host` import. 202 /// * [`exports::demo::Guest`](_2_world_exports::exports::demo::Guest) - 203 /// the generated structured used to invoke exports on the returned instance. 204 /// * [`HelloWorld`](_2_world_exports::HelloWorld) - 205 /// the overall generated structure representing our `world`. 206 /// 207 /// ```rust 208 /// use wasmtime::component::*; 209 /// use wasmtime::{Engine, Store}; 210 /// 211 #[doc = include_str!("./_2_world_exports.rs")] 212 /// 213 /// struct MyState { 214 /// // ... 215 /// } 216 /// 217 /// # mod rand { pub fn thread_rng() -> G { G } pub struct G; impl G { pub fn r#gen(&self) -> u32 { 0 } } } 218 /// // Note that the trait here is per-interface and within a submodule now. 219 /// impl my::project::host::Host for MyState { 220 /// fn gen_random_integer(&mut self) -> u32 { 221 /// rand::thread_rng().r#gen() 222 /// } 223 /// 224 /// fn sha256(&mut self, bytes: Vec<u8>) -> String { 225 /// // ... 226 /// # panic!() 227 /// } 228 /// } 229 /// 230 /// fn main() -> wasmtime::Result<()> { 231 /// # if true { return Ok(()) } 232 /// let engine = Engine::default(); 233 /// let component = Component::from_file(&engine, "./your-component.wasm")?; 234 /// 235 /// let mut linker = Linker::new(&engine); 236 /// HelloWorld::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 237 /// 238 /// let mut store = Store::new( 239 /// &engine, 240 /// MyState { /* ... */ }, 241 /// ); 242 /// let bindings = HelloWorld::instantiate(&mut store, &component, &linker)?; 243 /// 244 /// // Note that the `demo` method returns a `&exports::Demo::Guest` 245 /// // through which we can run the methods on that interface. 246 /// bindings.demo().call_run(&mut store)?; 247 /// Ok(()) 248 /// } 249 /// ``` 250 pub mod _2_world_exports; 251 252 /// Example of generating bindings for imported interfaces in a world. 253 /// 254 /// Notable parts of this example are: 255 /// 256 /// * Imported interfaces use the Rust module system to encapsulate themselves. 257 /// The interface imported here is `example:interface-imports/logging` so the 258 /// generated trait and types are located in 259 /// [`example::interface_imports::logging`][module]. 260 /// * Types in the `logging` interface are generated in the `logging` module, 261 /// for example [`Level`]. 262 /// * Generated types have implementations of [`ComponentType`], [`Lift`], and 263 /// [`Lower`] derived. 264 /// * The generated trait that host's must implement is always called [`Host`] 265 /// and is located in the generated module. 266 /// 267 /// [module]: _3_interface_imports::example::interface_imports::logging 268 /// [`Level`]: _3_interface_imports::example::interface_imports::logging::Level 269 /// [`Host`]: _3_interface_imports::example::interface_imports::logging::Host 270 /// [`ComponentType`]: crate::component::ComponentType 271 /// [`Lift`]: crate::component::Lift 272 /// [`Lower`]: crate::component::Lower 273 /// 274 /// ```rust 275 /// use wasmtime::component::bindgen; 276 /// use example::interface_imports::logging::Level; 277 /// 278 #[doc = include_str!("./_3_interface_imports.rs")] 279 /// 280 /// struct MyState { 281 /// // ... 282 /// } 283 /// 284 /// impl example::interface_imports::logging::Host for MyState { 285 /// fn log(&mut self, level: Level, msg: String) { 286 /// // ... 287 /// } 288 /// } 289 /// ``` 290 pub mod _3_interface_imports; 291 292 /// Example of generating bindings for imported resources in a world. 293 /// 294 /// Notable parts of this example are: 295 /// 296 /// * Imported resources from the host are represented as traits, in this case 297 /// [`HostLogger`]. 298 /// * The per-interface [`Host`] trait still exists but has a supertrait of 299 /// [`HostLogger`]. 300 /// * Resources are represented as [`Resource<T>`] and it's recommended to 301 /// specify a `with` key to indicate what host type you'd like to use for 302 /// each resource. 303 /// * A [`ResourceTable`] can be used to manage resources when working with 304 /// guests. 305 /// 306 /// [`Host`]: _4_imported_resources::example::imported_resources::logging::Host 307 /// [`HostLogger`]: _4_imported_resources::example::imported_resources::logging::HostLogger 308 /// [`Resource<T>`]: crate::component::Resource 309 /// [`ResourceTable`]: crate::component::ResourceTable 310 /// 311 /// ```rust 312 /// use wasmtime::Result; 313 /// use wasmtime::component::{bindgen, ResourceTable, Resource}; 314 /// use example::imported_resources::logging::{Level, Host, HostLogger}; 315 /// 316 #[doc = include_str!("./_4_imported_resources.rs")] 317 /// 318 /// #[derive(Default)] 319 /// struct MyState { 320 /// // Manages the mapping of `MyLogger` structures to `Resource<MyLogger>`. 321 /// table: ResourceTable, 322 /// } 323 /// 324 /// // There are no free-functions on `interface logging`, so this is an empty 325 /// // impl. 326 /// impl Host for MyState {} 327 /// 328 /// // This separate `HostLogger` trait serves to act as a namespace for just 329 /// // the `logger`-related resource methods. 330 /// impl HostLogger for MyState { 331 /// // A `constructor` in WIT maps to a `new` function in Rust. 332 /// fn new(&mut self, max_level: Level) -> Result<Resource<MyLogger>> { 333 /// let id = self.table.push(MyLogger { max_level })?; 334 /// Ok(id) 335 /// } 336 /// 337 /// fn get_max_level(&mut self, logger: Resource<MyLogger>) -> Result<Level> { 338 /// debug_assert!(!logger.owned()); 339 /// let logger = self.table.get(&logger)?; 340 /// Ok(logger.max_level) 341 /// } 342 /// 343 /// fn set_max_level(&mut self, logger: Resource<MyLogger>, level: Level) -> Result<()> { 344 /// debug_assert!(!logger.owned()); 345 /// let logger = self.table.get_mut(&logger)?; 346 /// logger.max_level = level; 347 /// Ok(()) 348 /// } 349 /// 350 /// fn log(&mut self, logger: Resource<MyLogger>, level: Level, msg: String) -> Result<()> { 351 /// debug_assert!(!logger.owned()); 352 /// let logger = self.table.get_mut(&logger)?; 353 /// if (level as u32) <= (logger.max_level as u32) { 354 /// println!("{msg}"); 355 /// } 356 /// Ok(()) 357 /// } 358 /// 359 /// fn drop(&mut self, logger: Resource<MyLogger>) -> Result<()> { 360 /// debug_assert!(logger.owned()); 361 /// let _logger: MyLogger = self.table.delete(logger)?; 362 /// // ... custom destruction logic here if necessary, otherwise 363 /// // a `Drop for MyLogger` would also work. 364 /// Ok(()) 365 /// } 366 /// } 367 /// 368 /// # fn main() {} 369 /// ``` 370 pub mod _4_imported_resources; 371 372 /// Example of all kinds of structures of exports from a world. 373 /// 374 /// * Top-level functions in a `world` are exported directly on the generated 375 /// structure such as [`call_run`]. 376 /// * All other exports are otherwise scoped with generated traits/types 377 /// in a top level [`exports`] module. 378 /// * Exported named interfaces are located at the root of the [`exports`] 379 /// module, such as [`exports::environment`]. 380 /// * Interfaces are all bound with a structure called `Guest` which has typed 381 /// functions for each export that can be called. For example 382 /// [`exports::environment::Guest`][guest1] and 383 /// [`exports::example::world_exports::units::Guest`][guest2]. 384 /// * Interfaces exported by their id are modeled with multiple namespacing 385 /// modules, such as [`exports::example::world_exports::units`][units]. 386 /// 387 /// [`call_run`]: _5_all_world_export_kinds::WithExports::call_run 388 /// [`exports`]: _5_all_world_export_kinds::exports 389 /// [`exports::environment`]: _5_all_world_export_kinds::exports::environment 390 /// [guest1]: _5_all_world_export_kinds::exports::environment::Guest 391 /// [guest2]: _5_all_world_export_kinds::exports::example::world_exports::units::Guest 392 /// [units]: _5_all_world_export_kinds::exports::example::world_exports::units 393 /// 394 /// ```rust 395 /// use wasmtime::{Result, Engine, Store}; 396 /// use wasmtime::component::{bindgen, Component, Linker, HasSelf}; 397 /// 398 #[doc = include_str!("./_5_all_world_export_kinds.rs")] 399 /// 400 /// struct MyState; 401 /// 402 /// impl WithExportsImports for MyState { 403 /// fn log(&mut self, msg: String) { 404 /// println!("{msg}"); 405 /// } 406 /// } 407 /// 408 /// fn main() -> Result<()> { 409 /// # if true { return Ok(()) } 410 /// let engine = Engine::default(); 411 /// let component = Component::from_file(&engine, "./your-component.wasm")?; 412 /// 413 /// let mut linker = Linker::new(&engine); 414 /// WithExports::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?; 415 /// 416 /// let mut store = Store::new(&engine, MyState); 417 /// let bindings = WithExports::instantiate(&mut store, &component, &linker)?; 418 /// 419 /// // top-level functions are exported directly on `WithExports` and are 420 /// // all prefixed with `call_*`. 421 /// bindings.call_run(&mut store)?; 422 /// 423 /// // exported named interfaces are named directly after their export name 424 /// // and the `&Guest` return value has `call_*` functions on it. 425 /// bindings.environment().call_set(&mut store, "key", "value")?; 426 /// let value = bindings.environment().call_get(&mut store, "key")?; 427 /// assert_eq!(value, "value"); 428 /// 429 /// // exported interfaces by id are similar to export-by-name except that 430 /// // the exported name is modeled after the full id, not just the name. 431 /// let units = bindings.example_world_exports_units(); 432 /// let bytes = 1 << 30 + 1 << 20; 433 /// let s = units.call_bytes_to_string(&mut store, bytes)?; 434 /// println!("{bytes} = {s}"); 435 /// 436 /// let (seconds, ns) = (1 << 20, 12345); 437 /// let s = units.call_duration_to_string(&mut store, seconds, ns)?; 438 /// println!("{seconds}s + {ns}ns = {s}"); 439 /// Ok(()) 440 /// } 441 /// ``` 442 pub mod _5_all_world_export_kinds; 443 444 /// Example of a world which exports a resource. 445 /// 446 /// * Guest resources are modeled as [`ResourceAny`]. Note that this type is not 447 /// specialized per-resource at this time so care must be taken to not mix 448 /// them up. 449 /// * Resource-related methods are a projection from a [`Guest`] structure, for 450 /// example to [`GuestLogger`] here. 451 /// * Resource-related methods all take a [`ResourceAny`] as an argument or 452 /// a return value. 453 /// * The [`ResourceAny`] must be explicitly dropped. 454 /// 455 /// [`ResourceAny`]: crate::component::ResourceAny 456 /// [`Guest`]: _6_exported_resources::exports::example::exported_resources::logging::Guest 457 /// [`GuestLogger`]: _6_exported_resources::exports::example::exported_resources::logging::GuestLogger 458 /// 459 /// ```rust 460 /// use wasmtime::{Result, Engine, Store}; 461 /// use wasmtime::component::{bindgen, Component, Linker}; 462 /// use self::exports::example::exported_resources::logging::Level; 463 /// 464 #[doc = include_str!("./_6_exported_resources.rs")] 465 /// 466 /// struct MyState; 467 /// 468 /// fn main() -> Result<()> { 469 /// # if true { return Ok(()) } 470 /// let engine = Engine::default(); 471 /// let component = Component::from_file(&engine, "./your-component.wasm")?; 472 /// 473 /// let linker = Linker::new(&engine); 474 /// // ... this small example has no imports so nothing is added here, but 475 /// // if you had imports this is where they'd go. 476 /// 477 /// let mut store = Store::new(&engine, MyState); 478 /// let bindings = ExportSomeResources::instantiate(&mut store, &component, &linker)?; 479 /// let guest = bindings.example_exported_resources_logging(); 480 /// let logger = guest.logger(); 481 /// 482 /// // Resource methods are all attached to `logger` and take the 483 /// // `ResourceAny` parameter explicitly. 484 /// let my_logger = logger.call_constructor(&mut store, Level::Warn)?; 485 /// assert_eq!(logger.call_get_max_level(&mut store, my_logger)?, Level::Warn); 486 /// logger.call_set_max_level(&mut store, my_logger, Level::Info)?; 487 /// 488 /// logger.call_log(&mut store, my_logger, Level::Debug, "hello!")?; 489 /// 490 /// // The `ResourceAny` type has no destructor but when the host is done 491 /// // with it it needs to invoke the guest-level destructor. 492 /// my_logger.resource_drop(&mut store)?; 493 /// 494 /// Ok(()) 495 /// } 496 /// ``` 497 pub mod _6_exported_resources; 498 499 /// Example of generating **async** bindings for imported resources in a world. 500 /// 501 /// Notable differences from [`_4_imported_resources`] are: 502 /// * async functions are used 503 /// * enabled async in bindgen! macro 504 /// 505 /// See [wasi_async_example](https://github.com/bytecodealliance/wasmtime/blob/main/examples/wasip1-async/main.rs) for async function calls on a host. 506 /// 507 /// ```rust 508 /// use wasmtime::Result; 509 /// use wasmtime::component::{bindgen, ResourceTable, Resource}; 510 /// use example::imported_resources::logging::{Level, Host, HostLogger}; 511 /// 512 #[doc = include_str!("./_7_async.rs")] 513 /// 514 /// #[derive(Default)] 515 /// struct MyState { 516 /// // Manages the mapping of `MyLogger` structures to `Resource<MyLogger>`. 517 /// table: ResourceTable, 518 /// } 519 /// 520 /// // There are no free-functions on `interface logging`, so this is an empty 521 /// // impl. 522 /// impl Host for MyState {} 523 /// 524 /// // This separate `HostLogger` trait serves to act as a namespace for just 525 /// // the `logger`-related resource methods. 526 /// impl HostLogger for MyState { 527 /// // A `constructor` in WIT maps to a `new` function in Rust. 528 /// async fn new(&mut self, max_level: Level) -> Result<Resource<MyLogger>> { 529 /// let id = self.table.push(MyLogger { max_level })?; 530 /// Ok(id) 531 /// } 532 /// 533 /// async fn get_max_level(&mut self, logger: Resource<MyLogger>) -> Result<Level> { 534 /// debug_assert!(!logger.owned()); 535 /// let logger = self.table.get(&logger)?; 536 /// Ok(logger.max_level) 537 /// } 538 /// 539 /// async fn set_max_level(&mut self, logger: Resource<MyLogger>, level: Level) -> Result<()> { 540 /// debug_assert!(!logger.owned()); 541 /// let logger = self.table.get_mut(&logger)?; 542 /// logger.max_level = level; 543 /// Ok(()) 544 /// } 545 /// 546 /// async fn log(&mut self, logger: Resource<MyLogger>, level: Level, msg: String) -> Result<()> { 547 /// debug_assert!(!logger.owned()); 548 /// let logger = self.table.get_mut(&logger)?; 549 /// if (level as u32) <= (logger.max_level as u32) { 550 /// println!("{msg}"); 551 /// } 552 /// Ok(()) 553 /// } 554 /// 555 /// async fn drop(&mut self, logger: Resource<MyLogger>) -> Result<()> { 556 /// debug_assert!(logger.owned()); 557 /// let _logger: MyLogger = self.table.delete(logger)?; 558 /// // ... custom destruction logic here if necessary, otherwise 559 /// // a `Drop for MyLogger` would also work. 560 /// Ok(()) 561 /// } 562 /// } 563 /// 564 /// # fn main() {} 565 /// ``` 566 pub mod _7_async; 567 568 /// Example of using [`StoreContextMut`] in imported functions. 569 /// 570 /// This is an example of using the `store` option to the `imports` 571 /// configuration of the [`bindgen!`](crate::component::bindgen) macro. Like 572 /// seen in previous examples a 573 /// [`MyWorldImports`](_8_store_in_imports::MyWorldImports) trait is generated 574 /// for `my-world`, but imports that have access to the store get added to a 575 /// separate trait with a `*WithStore` suffix, in this case 576 /// [`MyWorldImportsWithStore`](_8_store_in_imports::MyWorldImportsWithStore). 577 /// This second trait provides access to a [`StoreContextMut`]. 578 /// 579 /// [`StoreContextMut`]: crate::StoreContextMut 580 /// 581 /// ```rust 582 /// use wasmtime::component::{bindgen, HasData, Access, Accessor}; 583 /// use wasmtime::{StoreContextMut, AsContextMut}; 584 /// 585 #[doc = include_str!("./_8_store_in_imports.rs")] 586 /// 587 /// struct MyState { 588 /// // ... 589 /// } 590 /// 591 /// impl HasData for MyState { 592 /// type Data<'a> = &'a mut MyState; 593 /// } 594 /// 595 /// impl MyWorldImportsWithStore for MyState { 596 /// /// Synchronous functions that have access to the store are defined in 597 /// /// Rust as a normal `fn` with an `Access` as the first parameter. 598 /// fn sync_with_store<T>(mut host: Access<'_, T, Self>) { 599 /// // The `Access` type implements `AsContextMut` to manipulate and 600 /// // operate on the store. 601 /// let mut store: StoreContextMut<'_, T> = host.as_context_mut(); 602 /// 603 /// // The `Access` type can be used to get the `Data` projection of 604 /// // the `HasData` trait implementation above, in this case 605 /// // ourselves. 606 /// let my_state: &mut MyState = host.get(); 607 /// } 608 /// 609 /// /// Asynchronous functions that have access to the store are defined in 610 /// /// Rust as an `async fn` with an `Accessor` as the first parameter. 611 /// async fn async_with_store<T>(accessor: &Accessor<T, Self>) { 612 /// // The `Accessor` type does not implement `AsContextMut` directly 613 /// // and instead represents the ability to, synchronously, work with 614 /// // the store. Notably borrows into the store or `Self` cannot be 615 /// // persisted across await points 616 /// accessor.with(|mut access| { 617 /// // same as `sync_with_store` above 618 /// let mut store: StoreContextMut<'_, T> = access.as_context_mut(); 619 /// let my_state: &mut MyState = access.get(); 620 /// 621 /// // ... 622 /// }); 623 /// 624 /// some_function().await; 625 /// # async fn some_function() {} 626 /// 627 /// accessor.with(|mut access| { 628 /// // ... 629 /// }); 630 /// } 631 /// } 632 /// 633 /// // Functions that don't have access to the store are defined with 634 /// // `&mut self` indicating that they can only access data in `self`, not the 635 /// // entire store. 636 /// impl MyWorldImports for MyState { 637 /// fn sync_without_store(&mut self) { /* ... */ } 638 /// async fn async_without_store(&mut self) { /* ... */ } 639 /// } 640 /// 641 /// # fn main() {} 642 /// ``` 643 #[cfg(feature = "component-model-async")] 644 pub mod _8_store_in_imports; 645