wasmtime_wasi/p3/bindings.rs
1//! Auto-generated bindings for WASI interfaces.
2//!
3//! This module contains the output of the [`bindgen!`] macro when run over
4//! the `wasi:cli/imports` world.
5//!
6//! [`bindgen!`]: https://docs.rs/wasmtime/latest/wasmtime/component/macro.bindgen.html
7//!
8//! # Examples
9//!
10//! If you have a WIT world which refers to WASI interfaces you probably want to
11//! use this modules's bindings rather than generate fresh bindings. That can be
12//! done using the `with` option to [`bindgen!`]:
13//!
14//! ```rust
15//! use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
16//! use wasmtime::{Result, Engine, Config};
17//! use wasmtime::component::{Linker, HasSelf, ResourceTable};
18//!
19//! wasmtime::component::bindgen!({
20//! inline: "
21//! package example:wasi;
22//!
23//! // An example of extending the `wasi:cli/command` world with a
24//! // custom host interface.
25//! world my-world {
26//! include wasi:cli/command@0.3.0-rc-2026-02-09;
27//!
28//! import custom-host;
29//! }
30//!
31//! interface custom-host {
32//! my-custom-function: func();
33//! }
34//! ",
35//! path: "src/p3/wit",
36//! with: {
37//! "wasi": wasmtime_wasi::p3::bindings,
38//! },
39//! require_store_data_send: true,
40//! });
41//!
42//! struct MyState {
43//! ctx: WasiCtx,
44//! table: ResourceTable,
45//! }
46//!
47//! impl example::wasi::custom_host::Host for MyState {
48//! fn my_custom_function(&mut self) {
49//! // ..
50//! }
51//! }
52//!
53//! impl WasiView for MyState {
54//! fn ctx(&mut self) -> WasiCtxView<'_> {
55//! WasiCtxView{
56//! ctx: &mut self.ctx,
57//! table: &mut self.table,
58//! }
59//! }
60//! }
61//!
62//! fn main() -> Result<()> {
63//! let mut config = Config::default();
64//! config.wasm_component_model_async(true);
65//! let engine = Engine::new(&config)?;
66//! let mut linker: Linker<MyState> = Linker::new(&engine);
67//! wasmtime_wasi::p3::add_to_linker(&mut linker)?;
68//! example::wasi::custom_host::add_to_linker::<_, HasSelf<_>>(&mut linker, |state| state)?;
69//!
70//! // .. use `Linker` to instantiate component ...
71//!
72//! Ok(())
73//! }
74//! ```
75
76mod generated {
77 wasmtime::component::bindgen!({
78 path: "src/p3/wit",
79 world: "wasi:cli/command",
80 imports: {
81 "wasi:cli/stdin": store | tracing | trappable,
82 "wasi:cli/stdout": store | tracing | trappable,
83 "wasi:cli/stderr": store | tracing | trappable,
84 "wasi:filesystem/types.[method]descriptor.read-via-stream": store | tracing | trappable,
85 "wasi:filesystem/types.[method]descriptor.write-via-stream": store | tracing,
86 "wasi:filesystem/types.[method]descriptor.append-via-stream": store | tracing,
87 "wasi:filesystem/types.[method]descriptor.read-directory": store | tracing,
88 "wasi:sockets/types.[method]tcp-socket.bind": async | tracing | trappable,
89 "wasi:sockets/types.[method]tcp-socket.listen": store | tracing | trappable,
90 "wasi:sockets/types.[method]tcp-socket.send": store | tracing | trappable,
91 "wasi:sockets/types.[method]tcp-socket.receive": store | tracing | trappable,
92 "wasi:sockets/types.[method]udp-socket.bind": async | tracing | trappable,
93 "wasi:sockets/types.[method]udp-socket.connect": async | tracing | trappable,
94 default: tracing | trappable,
95 },
96 exports: { default: async | store },
97 with: {
98 "wasi:cli/terminal-input.terminal-input": crate::p3::cli::TerminalInput,
99 "wasi:cli/terminal-output.terminal-output": crate::p3::cli::TerminalOutput,
100 "wasi:filesystem/types.descriptor": crate::filesystem::Descriptor,
101 "wasi:sockets/types.tcp-socket": crate::sockets::TcpSocket,
102 "wasi:sockets/types.udp-socket": crate::sockets::UdpSocket,
103 },
104 trappable_error_type: {
105 "wasi:filesystem/types.error-code" => crate::p3::filesystem::FilesystemError,
106 "wasi:sockets/types.error-code" => crate::p3::sockets::SocketError,
107 },
108 });
109}
110pub use self::generated::LinkOptions;
111pub use self::generated::exports;
112pub use self::generated::wasi::*;
113
114/// Bindings to execute and run a `wasi:cli/command`.
115///
116/// This structure is automatically generated by `bindgen!`.
117///
118/// This can be used for a more "typed" view of executing a command component
119/// through the [`Command::wasi_cli_run`] method plus
120/// [`Guest::call_run`](exports::wasi::cli::run::Guest::call_run).
121///
122/// # Examples
123///
124/// ```no_run
125/// use wasmtime::{Engine, Result, Store, Config};
126/// use wasmtime::component::{Component, Linker, ResourceTable};
127/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
128/// use wasmtime_wasi::p3::bindings::Command;
129///
130/// // This example is an example shim of executing a component based on the
131/// // command line arguments provided to this program.
132/// #[tokio::main]
133/// async fn main() -> Result<()> {
134/// let args = std::env::args().skip(1).collect::<Vec<_>>();
135///
136/// // Configure and create `Engine`
137/// let mut config = Config::new();
138/// config.wasm_component_model_async(true);
139/// let engine = Engine::new(&config)?;
140///
141/// // Configure a `Linker` with WASI, compile a component based on
142/// // command line arguments, and then pre-instantiate it.
143/// let mut linker = Linker::<MyState>::new(&engine);
144/// wasmtime_wasi::p3::add_to_linker(&mut linker)?;
145/// let component = Component::from_file(&engine, &args[0])?;
146///
147///
148/// // Configure a `WasiCtx` based on this program's environment. Then
149/// // build a `Store` to instantiate into.
150/// let mut builder = WasiCtx::builder();
151/// builder.inherit_stdio().inherit_env().args(&args);
152/// let mut store = Store::new(
153/// &engine,
154/// MyState {
155/// ctx: builder.build(),
156/// table: ResourceTable::default(),
157/// },
158/// );
159///
160/// // Instantiate the component and we're off to the races.
161/// let command = Command::instantiate_async(&mut store, &component, &linker).await?;
162/// let program_result = store.run_concurrent(async move |store| {
163/// command.wasi_cli_run().call_run(store).await
164/// }).await??;
165/// match program_result {
166/// Ok(()) => Ok(()),
167/// Err(()) => std::process::exit(1),
168/// }
169/// }
170///
171/// struct MyState {
172/// ctx: WasiCtx,
173/// table: ResourceTable,
174/// }
175///
176/// impl WasiView for MyState {
177/// fn ctx(&mut self) -> WasiCtxView<'_> {
178/// WasiCtxView{
179/// ctx: &mut self.ctx,
180/// table: &mut self.table,
181/// }
182/// }
183/// }
184/// ```
185///
186/// ---
187pub use self::generated::Command;
188
189/// Pre-instantiated analog of [`Command`]
190///
191/// This can be used to front-load work such as export lookup before
192/// instantiation.
193///
194/// # Examples
195///
196/// ```no_run
197/// use wasmtime::{Engine, Result, Store, Config};
198/// use wasmtime::component::{Linker, Component, ResourceTable};
199/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
200/// use wasmtime_wasi::p3::bindings::CommandPre;
201///
202/// // This example is an example shim of executing a component based on the
203/// // command line arguments provided to this program.
204/// #[tokio::main]
205/// async fn main() -> Result<()> {
206/// let args = std::env::args().skip(1).collect::<Vec<_>>();
207///
208/// // Configure and create `Engine`
209/// let mut config = Config::new();
210/// config.wasm_component_model_async(true);
211/// let engine = Engine::new(&config)?;
212///
213/// // Configure a `Linker` with WASI, compile a component based on
214/// // command line arguments, and then pre-instantiate it.
215/// let mut linker = Linker::<MyState>::new(&engine);
216/// wasmtime_wasi::p3::add_to_linker(&mut linker)?;
217/// let component = Component::from_file(&engine, &args[0])?;
218/// let pre = CommandPre::new(linker.instantiate_pre(&component)?)?;
219///
220///
221/// // Configure a `WasiCtx` based on this program's environment. Then
222/// // build a `Store` to instantiate into.
223/// let mut builder = WasiCtx::builder();
224/// builder.inherit_stdio().inherit_env().args(&args);
225/// let mut store = Store::new(
226/// &engine,
227/// MyState {
228/// ctx: builder.build(),
229/// table: ResourceTable::default(),
230/// },
231/// );
232///
233/// // Instantiate the component and we're off to the races.
234/// let command = pre.instantiate_async(&mut store).await?;
235/// // TODO: Construct an accessor from `store` to call `run`
236/// // https://github.com/bytecodealliance/wasmtime/issues/11249
237/// //let program_result = command.wasi_cli_run().call_run(&mut store).await?;
238/// let program_result = todo!();
239/// match program_result {
240/// Ok(()) => Ok(()),
241/// Err(()) => std::process::exit(1),
242/// }
243/// }
244///
245/// struct MyState {
246/// ctx: WasiCtx,
247/// table: ResourceTable,
248/// }
249///
250/// impl WasiView for MyState {
251/// fn ctx(&mut self) -> WasiCtxView<'_> {
252/// WasiCtxView{
253/// ctx: &mut self.ctx,
254/// table: &mut self.table,
255/// }
256/// }
257/// }
258/// ```
259///
260/// ---
261// TODO: Make this public, once `CommandPre` can be used for
262// calling exports
263// https://github.com/bytecodealliance/wasmtime/issues/11249
264#[doc(hidden)]
265pub use self::generated::CommandPre;
266
267pub use self::generated::CommandIndices;