Skip to main content

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;
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 | trappable,
86            "wasi:filesystem/types.[method]descriptor.append-via-stream": store | tracing | trappable,
87            "wasi:filesystem/types.[method]descriptor.read-directory": store | tracing | trappable,
88            "wasi:sockets/types.[method]tcp-socket.bind": async | tracing | trappable,
89            "wasi:sockets/types.[method]tcp-socket.listen": async | 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.[static]udp-socket.create": async | tracing | trappable,
93            "wasi:sockets/types.[method]udp-socket.bind": async | tracing | trappable,
94            "wasi:sockets/types.[method]udp-socket.connect": async | tracing | trappable,
95            default: tracing | trappable,
96        },
97        exports: { default: async | store },
98        with: {
99            "wasi:cli/terminal-input.terminal-input": crate::p3::cli::TerminalInput,
100            "wasi:cli/terminal-output.terminal-output": crate::p3::cli::TerminalOutput,
101            "wasi:filesystem/types.descriptor": crate::filesystem::Descriptor,
102            "wasi:sockets/types.tcp-socket": crate::sockets::TcpSocket,
103            "wasi:sockets/types.udp-socket": crate::sockets::UdpSocket,
104        },
105        trappable_error_type: {
106            "wasi:filesystem/types.error-code" => crate::p3::filesystem::FilesystemError,
107            "wasi:sockets/types.error-code" => crate::p3::sockets::SocketError,
108        },
109        named_imports: {
110            "wasi:clocks/monotonic-clock": crate::NamedId,
111            "wasi:clocks/system-clock": crate::NamedId,
112            "wasi:random/random": crate::NamedId,
113            "wasi:random/insecure": crate::NamedId,
114            "wasi:random/insecure-seed": crate::NamedId,
115            "wasi:cli/exit": crate::NamedId,
116            "wasi:cli/environment": crate::NamedId,
117            "wasi:cli/stdin": crate::NamedId,
118            "wasi:cli/stdout": crate::NamedId,
119            "wasi:cli/stderr": crate::NamedId,
120            "wasi:cli/terminal-input": crate::NamedId,
121            "wasi:cli/terminal-output": crate::NamedId,
122            "wasi:cli/terminal-stdin": crate::NamedId,
123            "wasi:cli/terminal-stdout": crate::NamedId,
124            "wasi:cli/terminal-stderr": crate::NamedId,
125            "wasi:filesystem/types": crate::NamedId,
126            "wasi:filesystem/preopens": crate::NamedId,
127            "wasi:sockets/types": crate::NamedId,
128            "wasi:sockets/ip-name-lookup": crate::NamedId,
129        },
130    });
131}
132pub use self::generated::LinkOptions;
133pub use self::generated::exports;
134pub use self::generated::named_imports;
135pub use self::generated::wasi::*;
136
137/// Bindings to execute and run a `wasi:cli/command`.
138///
139/// This structure is automatically generated by `bindgen!`.
140///
141/// This can be used for a more "typed" view of executing a command component
142/// through the [`Command::wasi_cli_run`] method plus
143/// [`Guest::call_run`](exports::wasi::cli::run::Guest::call_run).
144///
145/// # Examples
146///
147/// ```no_run
148/// use wasmtime::{Engine, Result, Store, Config};
149/// use wasmtime::component::{Component, Linker, ResourceTable};
150/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
151/// use wasmtime_wasi::p3::bindings::Command;
152///
153/// // This example is an example shim of executing a component based on the
154/// // command line arguments provided to this program.
155/// #[tokio::main]
156/// async fn main() -> Result<()> {
157///     let args = std::env::args().skip(1).collect::<Vec<_>>();
158///
159///     // Configure and create `Engine`
160///     let mut config = Config::new();
161///     config.wasm_component_model_async(true);
162///     let engine = Engine::new(&config)?;
163///
164///     // Configure a `Linker` with WASI, compile a component based on
165///     // command line arguments, and then pre-instantiate it.
166///     let mut linker = Linker::<MyState>::new(&engine);
167///     wasmtime_wasi::p3::add_to_linker(&mut linker)?;
168///     let component = Component::from_file(&engine, &args[0])?;
169///
170///
171///     // Configure a `WasiCtx` based on this program's environment. Then
172///     // build a `Store` to instantiate into.
173///     let mut builder = WasiCtx::builder();
174///     builder.inherit_stdio().inherit_env().args(&args);
175///     let mut store = Store::new(
176///         &engine,
177///         MyState {
178///             ctx: builder.build(),
179///             table: ResourceTable::default(),
180///         },
181///     );
182///
183///     // Instantiate the component and we're off to the races.
184///     let command = Command::instantiate_async(&mut store, &component, &linker).await?;
185///     let program_result = store.run_concurrent(async move |store| {
186///         command.wasi_cli_run().call_run(store).await
187///     }).await??;
188///     match program_result {
189///         Ok(()) => Ok(()),
190///         Err(()) => std::process::exit(1),
191///     }
192/// }
193///
194/// struct MyState {
195///     ctx: WasiCtx,
196///     table: ResourceTable,
197/// }
198///
199/// impl WasiView for MyState {
200///     fn ctx(&mut self) -> WasiCtxView<'_> {
201///         WasiCtxView{
202///             ctx: &mut self.ctx,
203///             table: &mut self.table,
204///         }
205///     }
206/// }
207/// ```
208///
209/// ---
210pub use self::generated::Command;
211
212/// Pre-instantiated analog of [`Command`]
213///
214/// This can be used to front-load work such as export lookup before
215/// instantiation.
216///
217/// # Examples
218///
219/// ```no_run
220/// use wasmtime::{Engine, Result, Store, Config};
221/// use wasmtime::component::{Linker, Component, ResourceTable};
222/// use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};
223/// use wasmtime_wasi::p3::bindings::CommandPre;
224///
225/// // This example is an example shim of executing a component based on the
226/// // command line arguments provided to this program.
227/// #[tokio::main]
228/// async fn main() -> Result<()> {
229///     let args = std::env::args().skip(1).collect::<Vec<_>>();
230///
231///     // Configure and create `Engine`
232///     let mut config = Config::new();
233///     config.wasm_component_model_async(true);
234///     let engine = Engine::new(&config)?;
235///
236///     // Configure a `Linker` with WASI, compile a component based on
237///     // command line arguments, and then pre-instantiate it.
238///     let mut linker = Linker::<MyState>::new(&engine);
239///     wasmtime_wasi::p3::add_to_linker(&mut linker)?;
240///     let component = Component::from_file(&engine, &args[0])?;
241///     let pre = CommandPre::new(linker.instantiate_pre(&component)?)?;
242///
243///
244///     // Configure a `WasiCtx` based on this program's environment. Then
245///     // build a `Store` to instantiate into.
246///     let mut builder = WasiCtx::builder();
247///     builder.inherit_stdio().inherit_env().args(&args);
248///     let mut store = Store::new(
249///         &engine,
250///         MyState {
251///             ctx: builder.build(),
252///             table: ResourceTable::default(),
253///         },
254///     );
255///
256///     // Instantiate the component and we're off to the races.
257///     let command = pre.instantiate_async(&mut store).await?;
258///     // TODO: Construct an accessor from `store` to call `run`
259///     // https://github.com/bytecodealliance/wasmtime/issues/11249
260///     //let program_result = command.wasi_cli_run().call_run(&mut store).await?;
261///     let program_result = todo!();
262///     match program_result {
263///         Ok(()) => Ok(()),
264///         Err(()) => std::process::exit(1),
265///     }
266/// }
267///
268/// struct MyState {
269///     ctx: WasiCtx,
270///     table: ResourceTable,
271/// }
272///
273/// impl WasiView for MyState {
274///     fn ctx(&mut self) -> WasiCtxView<'_> {
275///         WasiCtxView{
276///             ctx: &mut self.ctx,
277///             table: &mut self.table,
278///         }
279///     }
280/// }
281/// ```
282///
283/// ---
284// TODO: Make this public, once `CommandPre` can be used for
285// calling exports
286// https://github.com/bytecodealliance/wasmtime/issues/11249
287#[doc(hidden)]
288pub use self::generated::CommandPre;
289
290pub use self::generated::CommandIndices;