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