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 closure 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 ///     let mut linker = Linker::new(&engine);
110 ///     HelloWorld::add_to_linker(&mut linker, |state: &mut MyState| state)?;
111 ///
112 ///     // As with the core wasm API of Wasmtime instantiation occurs within a
113 ///     // `Store`. The bindings structure contains an `instantiate` method which
114 ///     // takes the store, component, and linker. This returns the `bindings`
115 ///     // structure which is an instance of `HelloWorld` and supports typed access
116 ///     // to the exports of the component.
117 ///     let mut store = Store::new(
118 ///         &engine,
119 ///         MyState {
120 ///             name: "me".to_string(),
121 ///         },
122 ///     );
123 ///     let bindings = HelloWorld::instantiate(&mut store, &component, &linker)?;
124 ///
125 ///     // Here our `greet` function doesn't take any parameters for the component,
126 ///     // but in the Wasmtime embedding API the first argument is always a `Store`.
127 ///     bindings.call_greet(&mut store)?;
128 ///     Ok(())
129 /// }
130 /// ```
131 pub mod _0_hello_world;
132 
133 /// An example of generated bindings for top-level imported functions and
134 /// interfaces into a world.
135 ///
136 /// The code used to generate this module is:
137 ///
138 /// ```rust
139 /// use wasmtime::component::*;
140 /// use wasmtime::{Engine, Store};
141 ///
142 #[doc = include_str!("./_1_world_imports.rs")]
143 ///
144 /// struct MyState {
145 ///     // ...
146 /// }
147 ///
148 /// impl my_custom_host::Host for MyState {
149 ///     fn tick(&mut self) {
150 ///         todo!()
151 ///     }
152 /// }
153 ///
154 /// impl MyWorldImports for MyState {
155 ///     fn greet(&mut self) -> String {
156 ///         todo!()
157 ///     }
158 ///
159 ///     fn log(&mut self, msg: String) {
160 ///         println!("{msg}");
161 ///     }
162 /// }
163 ///
164 /// fn main() -> wasmtime::Result<()> {
165 /// #   if true { return Ok(()) }
166 ///     let engine = Engine::default();
167 ///     let component = Component::from_file(&engine, "./your-component.wasm")?;
168 ///
169 ///     let mut linker = Linker::new(&engine);
170 ///     MyWorld::add_to_linker(&mut linker, |state: &mut MyState| state)?;
171 ///
172 ///     let mut store = Store::new(
173 ///         &engine,
174 ///         MyState { /* ... */ },
175 ///     );
176 ///     let bindings = MyWorld::instantiate(&mut store, &component, &linker)?;
177 ///
178 ///     // ... NB: this world has no exports just yet so not much can be done
179 ///     // with `bindings`.
180 ///
181 ///     Ok(())
182 /// }
183 /// ```
184 pub mod _1_world_imports;
185 
186 /// An example of generated bindings for top-level exported functions for a
187 /// world.
188 ///
189 /// Some notable generated items here are:
190 ///
191 /// * [`my::project::host::Host`](_2_world_exports::my::project::host::Host) -
192 ///   the generated trait for the `interface host` import.
193 /// * [`exports::demo::Guest`](_2_world_exports::exports::demo::Guest) -
194 ///   the generated structured used to invoke exports on the returned instance.
195 /// * [`HelloWorld`](_2_world_exports::HelloWorld) -
196 ///   the overall generated structure representing our `world`.
197 ///
198 /// ```rust
199 /// use wasmtime::component::*;
200 /// use wasmtime::{Engine, Store};
201 ///
202 #[doc = include_str!("./_2_world_exports.rs")]
203 ///
204 /// struct MyState {
205 ///     // ...
206 /// }
207 ///
208 /// # mod rand { pub fn thread_rng() -> G { G } pub struct G; impl G { pub fn r#gen(&self) -> u32 { 0 } } }
209 /// // Note that the trait here is per-interface and within a submodule now.
210 /// impl my::project::host::Host for MyState {
211 ///     fn gen_random_integer(&mut self) -> u32 {
212 ///         rand::thread_rng().r#gen()
213 ///     }
214 ///
215 ///     fn sha256(&mut self, bytes: Vec<u8>) -> String {
216 ///         // ...
217 /// #       panic!()
218 ///     }
219 /// }
220 ///
221 /// fn main() -> wasmtime::Result<()> {
222 /// #   if true { return Ok(()) }
223 ///     let engine = Engine::default();
224 ///     let component = Component::from_file(&engine, "./your-component.wasm")?;
225 ///
226 ///     let mut linker = Linker::new(&engine);
227 ///     HelloWorld::add_to_linker(&mut linker, |state: &mut MyState| state)?;
228 ///
229 ///     let mut store = Store::new(
230 ///         &engine,
231 ///         MyState { /* ... */ },
232 ///     );
233 ///     let bindings = HelloWorld::instantiate(&mut store, &component, &linker)?;
234 ///
235 ///     // Note that the `demo` method returns a `&exports::Demo::Guest`
236 ///     // through which we can run the methods on that interface.
237 ///     bindings.demo().call_run(&mut store)?;
238 ///     Ok(())
239 /// }
240 /// ```
241 pub mod _2_world_exports;
242 
243 /// Example of generating bindings for imported interfaces in a world.
244 ///
245 /// Notable parts of this example are:
246 ///
247 /// * Imported interfaces use the Rust module system to encapsulate themselves.
248 ///   The interface imported here is `example:interface-imports/logging` so the
249 ///   generated trait and types are located in
250 ///   [`example::interface_imports::logging`][module].
251 /// * Types in the `logging` interface are generated in the `logging` module,
252 ///   for example [`Level`].
253 /// * Generated types have implementations of [`ComponentType`], [`Lift`], and
254 ///   [`Lower`] derived.
255 /// * The generated trait that host's must implement is always called [`Host`]
256 ///   and is located in the generated module.
257 ///
258 /// [module]: _3_interface_imports::example::interface_imports::logging
259 /// [`Level`]: _3_interface_imports::example::interface_imports::logging::Level
260 /// [`Host`]: _3_interface_imports::example::interface_imports::logging::Host
261 /// [`ComponentType`]: crate::component::ComponentType
262 /// [`Lift`]: crate::component::Lift
263 /// [`Lower`]: crate::component::Lower
264 ///
265 /// ```rust
266 /// use wasmtime::component::bindgen;
267 /// use example::interface_imports::logging::Level;
268 ///
269 #[doc = include_str!("./_3_interface_imports.rs")]
270 ///
271 /// struct MyState {
272 ///     // ...
273 /// }
274 ///
275 /// impl example::interface_imports::logging::Host for MyState {
276 ///     fn log(&mut self, level: Level, msg: String) {
277 ///         // ...
278 ///     }
279 /// }
280 /// ```
281 pub mod _3_interface_imports;
282 
283 /// Example of generating bindings for imported resources in a world.
284 ///
285 /// Notable parts of this example are:
286 ///
287 /// * Imported resources from the host are represented as traits, in this case
288 ///   [`HostLogger`].
289 /// * The per-interface [`Host`] trait still exists but has a supertrait of
290 ///   [`HostLogger`].
291 /// * Resources are represented as [`Resource<T>`] and it's recommended to
292 ///   specify a `with` key to indicate what host type you'd like to use for
293 ///   each resource.
294 /// * A [`ResourceTable`] can be used to manage resources when working with
295 ///   guests.
296 ///
297 /// [`Host`]: _4_imported_resources::example::imported_resources::logging::Host
298 /// [`HostLogger`]: _4_imported_resources::example::imported_resources::logging::HostLogger
299 /// [`Resource<T>`]: crate::component::Resource
300 /// [`ResourceTable`]: crate::component::ResourceTable
301 ///
302 /// ```rust
303 /// use wasmtime::Result;
304 /// use wasmtime::component::{bindgen, ResourceTable, Resource};
305 /// use example::imported_resources::logging::{Level, Host, HostLogger};
306 ///
307 #[doc = include_str!("./_4_imported_resources.rs")]
308 ///
309 /// #[derive(Default)]
310 /// struct MyState {
311 ///     // Manages the mapping of `MyLogger` structures to `Resource<MyLogger>`.
312 ///     table: ResourceTable,
313 /// }
314 ///
315 /// // There are no free-functions on `interface logging`, so this is an empty
316 /// // impl.
317 /// impl Host for MyState {}
318 ///
319 /// // This separate `HostLogger` trait serves to act as a namespace for just
320 /// // the `logger`-related resource methods.
321 /// impl HostLogger for MyState {
322 ///     // A `constructor` in WIT maps to a `new` function in Rust.
323 ///     fn new(&mut self, max_level: Level) -> Result<Resource<MyLogger>> {
324 ///         let id = self.table.push(MyLogger { max_level })?;
325 ///         Ok(id)
326 ///     }
327 ///
328 ///     fn get_max_level(&mut self, logger: Resource<MyLogger>) -> Result<Level> {
329 ///         debug_assert!(!logger.owned());
330 ///         let logger = self.table.get(&logger)?;
331 ///         Ok(logger.max_level)
332 ///     }
333 ///
334 ///     fn set_max_level(&mut self, logger: Resource<MyLogger>, level: Level) -> Result<()> {
335 ///         debug_assert!(!logger.owned());
336 ///         let logger = self.table.get_mut(&logger)?;
337 ///         logger.max_level = level;
338 ///         Ok(())
339 ///     }
340 ///
341 ///     fn log(&mut self, logger: Resource<MyLogger>, level: Level, msg: String) -> Result<()> {
342 ///         debug_assert!(!logger.owned());
343 ///         let logger = self.table.get_mut(&logger)?;
344 ///         if (level as u32) <= (logger.max_level as u32) {
345 ///             println!("{msg}");
346 ///         }
347 ///         Ok(())
348 ///     }
349 ///
350 ///     fn drop(&mut self, logger: Resource<MyLogger>) -> Result<()> {
351 ///         debug_assert!(logger.owned());
352 ///         let _logger: MyLogger = self.table.delete(logger)?;
353 ///         // ... custom destruction logic here if necessary, otherwise
354 ///         // a `Drop for MyLogger` would also work.
355 ///         Ok(())
356 ///     }
357 /// }
358 ///
359 /// # fn main() {}
360 /// ```
361 pub mod _4_imported_resources;
362 
363 /// Example of all kinds of structures of exports from a world.
364 ///
365 /// * Top-level functions in a `world` are exported directly on the generated
366 ///   structure such as [`call_run`].
367 /// * All other exports are otherwise scoped with generated traits/types
368 ///   in a top level [`exports`] module.
369 /// * Exported named interfaces are located at the root of the [`exports`]
370 ///   module, such as [`exports::environment`].
371 /// * Interfaces are all bound with a structure called `Guest` which has typed
372 ///   functions for each export that can be called. For example
373 ///   [`exports::environment::Guest`][guest1] and
374 ///   [`exports::example::world_exports::units::Guest`][guest2].
375 /// * Interfaces exported by their id are modeled with multiple namespacing
376 ///   modules, such as [`exports::example::world_exports::units`][units].
377 ///
378 /// [`call_run`]: _5_all_world_export_kinds::WithExports::call_run
379 /// [`exports`]: _5_all_world_export_kinds::exports
380 /// [`exports::environment`]: _5_all_world_export_kinds::exports::environment
381 /// [guest1]: _5_all_world_export_kinds::exports::environment::Guest
382 /// [guest2]: _5_all_world_export_kinds::exports::example::world_exports::units::Guest
383 /// [units]: _5_all_world_export_kinds::exports::example::world_exports::units
384 ///
385 /// ```rust
386 /// use wasmtime::{Result, Engine, Store};
387 /// use wasmtime::component::{bindgen, Component, Linker};
388 ///
389 #[doc = include_str!("./_5_all_world_export_kinds.rs")]
390 ///
391 /// struct MyState;
392 ///
393 /// impl WithExportsImports for MyState {
394 ///     fn log(&mut self, msg: String) {
395 ///         println!("{msg}");
396 ///     }
397 /// }
398 ///
399 /// fn main() -> Result<()> {
400 /// #   if true { return Ok(()) }
401 ///     let engine = Engine::default();
402 ///     let component = Component::from_file(&engine, "./your-component.wasm")?;
403 ///
404 ///     let mut linker = Linker::new(&engine);
405 ///     WithExports::add_to_linker(&mut linker, |state: &mut MyState| state)?;
406 ///
407 ///     let mut store = Store::new(&engine, MyState);
408 ///     let bindings = WithExports::instantiate(&mut store, &component, &linker)?;
409 ///
410 ///     // top-level functions are exported directly on `WithExports` and are
411 ///     // all prefixed with `call_*`.
412 ///     bindings.call_run(&mut store)?;
413 ///
414 ///     // exported named interfaces are named directly after their export name
415 ///     // and the `&Guest` return value has `call_*` functions on it.
416 ///     bindings.environment().call_set(&mut store, "key", "value")?;
417 ///     let value = bindings.environment().call_get(&mut store, "key")?;
418 ///     assert_eq!(value, "value");
419 ///
420 ///     // exported interfaces by id are similar to export-by-name except that
421 ///     // the exported name is modeled after the full id, not just the name.
422 ///     let units = bindings.example_world_exports_units();
423 ///     let bytes = 1 << 30 + 1 << 20;
424 ///     let s = units.call_bytes_to_string(&mut store, bytes)?;
425 ///     println!("{bytes} = {s}");
426 ///
427 ///     let (seconds, ns) = (1 << 20, 12345);
428 ///     let s = units.call_duration_to_string(&mut store, seconds, ns)?;
429 ///     println!("{seconds}s + {ns}ns = {s}");
430 ///     Ok(())
431 /// }
432 /// ```
433 pub mod _5_all_world_export_kinds;
434 
435 /// Example of a world which exports a resource.
436 ///
437 /// * Guest resources are modeled as [`ResourceAny`]. Note that this type is not
438 ///   specialized per-resource at this time so care must be taken to not mix
439 ///   them up.
440 /// * Resource-related methods are a projection from a [`Guest`] structure, for
441 ///   example to [`GuestLogger`] here.
442 /// * Resource-related methods all take a [`ResourceAny`] as an argument or
443 ///   a return value.
444 /// * The [`ResourceAny`] must be explicitly dropped.
445 ///
446 /// [`ResourceAny`]: crate::component::ResourceAny
447 /// [`Guest`]: _6_exported_resources::exports::example::exported_resources::logging::Guest
448 /// [`GuestLogger`]: _6_exported_resources::exports::example::exported_resources::logging::GuestLogger
449 ///
450 /// ```rust
451 /// use wasmtime::{Result, Engine, Store};
452 /// use wasmtime::component::{bindgen, Component, Linker};
453 /// use self::exports::example::exported_resources::logging::Level;
454 ///
455 #[doc = include_str!("./_6_exported_resources.rs")]
456 ///
457 /// struct MyState;
458 ///
459 /// fn main() -> Result<()> {
460 /// #   if true { return Ok(()) }
461 ///     let engine = Engine::default();
462 ///     let component = Component::from_file(&engine, "./your-component.wasm")?;
463 ///
464 ///     let linker = Linker::new(&engine);
465 ///     // ... this small example has no imports so nothing is added here, but
466 ///     // if you had imports this is where they'd go.
467 ///
468 ///     let mut store = Store::new(&engine, MyState);
469 ///     let bindings = ExportSomeResources::instantiate(&mut store, &component, &linker)?;
470 ///     let guest = bindings.example_exported_resources_logging();
471 ///     let logger = guest.logger();
472 ///
473 ///     // Resource methods are all attached to `logger` and take the
474 ///     // `ResourceAny` parameter explicitly.
475 ///     let my_logger = logger.call_constructor(&mut store, Level::Warn)?;
476 ///     assert_eq!(logger.call_get_max_level(&mut store, my_logger)?, Level::Warn);
477 ///     logger.call_set_max_level(&mut store, my_logger, Level::Info)?;
478 ///
479 ///     logger.call_log(&mut store, my_logger, Level::Debug, "hello!")?;
480 ///
481 ///     // The `ResourceAny` type has no destructor but when the host is done
482 ///     // with it it needs to invoke the guest-level destructor.
483 ///     my_logger.resource_drop(&mut store)?;
484 ///
485 ///     Ok(())
486 /// }
487 /// ```
488 pub mod _6_exported_resources;
489 
490 /// Example of generating **async** bindings for imported resources in a world.
491 ///
492 /// Notable differences from [`_4_imported_resources`] are:
493 /// * async functions are used
494 /// * enabled async in bindgen! macro
495 ///
496 /// See [wasi_async_example](https://github.com/bytecodealliance/wasmtime/tree/main/examples/wasi-async) for async function calls on a host.
497 ///
498 /// ```rust
499 /// use wasmtime::Result;
500 /// use wasmtime::component::{bindgen, ResourceTable, Resource};
501 /// use example::imported_resources::logging::{Level, Host, HostLogger};
502 ///
503 #[doc = include_str!("./_7_async.rs")]
504 ///
505 /// #[derive(Default)]
506 /// struct MyState {
507 ///     // Manages the mapping of `MyLogger` structures to `Resource<MyLogger>`.
508 ///     table: ResourceTable,
509 /// }
510 ///
511 /// // There are no free-functions on `interface logging`, so this is an empty
512 /// // impl.
513 /// impl Host for MyState {}
514 ///
515 /// // This separate `HostLogger` trait serves to act as a namespace for just
516 /// // the `logger`-related resource methods.
517 /// impl HostLogger for MyState {
518 ///     // A `constructor` in WIT maps to a `new` function in Rust.
519 ///     async fn new(&mut self, max_level: Level) -> Result<Resource<MyLogger>> {
520 ///         let id = self.table.push(MyLogger { max_level })?;
521 ///         Ok(id)
522 ///     }
523 ///
524 ///     async fn get_max_level(&mut self, logger: Resource<MyLogger>) -> Result<Level> {
525 ///         debug_assert!(!logger.owned());
526 ///         let logger = self.table.get(&logger)?;
527 ///         Ok(logger.max_level)
528 ///     }
529 ///
530 ///     async fn set_max_level(&mut self, logger: Resource<MyLogger>, level: Level) -> Result<()> {
531 ///         debug_assert!(!logger.owned());
532 ///         let logger = self.table.get_mut(&logger)?;
533 ///         logger.max_level = level;
534 ///         Ok(())
535 ///     }
536 ///
537 ///     async fn log(&mut self, logger: Resource<MyLogger>, level: Level, msg: String) -> Result<()> {
538 ///         debug_assert!(!logger.owned());
539 ///         let logger = self.table.get_mut(&logger)?;
540 ///         if (level as u32) <= (logger.max_level as u32) {
541 ///             println!("{msg}");
542 ///         }
543 ///         Ok(())
544 ///     }
545 ///
546 ///     async fn drop(&mut self, logger: Resource<MyLogger>) -> Result<()> {
547 ///         debug_assert!(logger.owned());
548 ///         let _logger: MyLogger = self.table.delete(logger)?;
549 ///         // ... custom destruction logic here if necessary, otherwise
550 ///         // a `Drop for MyLogger` would also work.
551 ///         Ok(())
552 ///     }
553 /// }
554 ///
555 /// # fn main() {}
556 /// ```
557 pub mod _7_async;
558