wasi/lib.rs
1//! Raw API bindings to the [WebAssembly System Interface (WASI)][WASI]
2//!
3//! [WASI]: https://github.com/WebAssembly/WASI
4//!
5//! This crate provides Rust API bindings to the imports of [WASI] [worlds] such
6//! as:
7//!
8//! * [`wasi:cli/command`]
9//! * [`wasi:http/proxy`]
10//!
11//! This crate is procedurally generated with the [`wit-bindgen`] bindings
12//! generator. Note that generated code is published to crates.io to slim this
13//! crate down in terms of build dependencies and resources.
14//!
15//! # What is WASI?
16//!
17//! [WASI] is a set of APIs defined for the WebAssembly [Component Model] to
18//! help components interact with the outside world. Core WebAssembly has no
19//! intrinsic ability to access the host, for example `println!` don't work, but
20//! [WASI] defines how to do so with the [`wasi:cli/stdio`] package.
21//!
22//! [WASI] is defined by an IDL called [WIT] using files that have the extension
23//! `*.wit`. [WASI] and [WIT] are themselves then both defined in terms of the
24//! [Component Model] in terms of types available and base semantics for APIs.
25//!
26//! [WASI] defines a number of standard "worlds" which are a description of a
27//! what a WebAssembly component can import from an embedding and must export to
28//! an embedding. An example world is [`wasi:cli/command`] which is a world for
29//! running CLI applications. This world provides basic system utilities such as
30//! clocks, a filesystem, CLI arguments, etc. The one required export is a main
31//! function.
32//!
33//! The purpose of this crate is to provide pregenerated bindings to access
34//! [WASI]-defined imports available to components.
35//!
36//! # What is a Component?
37//!
38//! An important aspect of [WASI] is that it is defined in terms of the
39//! [Component Model]. The [Component Model] is a proposal for WebAssembly which
40//! is a new format for wasm binaries, a component. A component contains "core"
41//! WebAssembly modules (which are [standard WebAssembly modules]) but also has
42//! the ability to do more:
43//!
44//! * A component can contain multiple core WebAssembly modules.
45//! * Types used with component imports and exports are more comprehensive than
46//! core WebAssembly. Core WebAssembly provides integers and floats, for
47//! example, and components build on this and add strings, records (aka a Rust
48//! `struct`), variants (aka a Rust `enum`), and resources (think a file
49//! descriptor on Unix).
50//! * A component provides procedural instructions of how to instantiate its
51//! internal core WebAssembly modules with the imports it has.
52//!
53//! The [Component Model] is a not considered an official WebAssembly standard
54//! at this time. It has been in development for 5 years (as of January 2024),
55//! however, and the WASI 0.2.0 milestone (more on versioning in a moment) in
56//! January 2024 represents a concrete target for ecosystems to use. Runtimes
57//! such as [Wasmtime] support the [Component Model] for out-of-browser usage
58//! and [jco] is an example of how components can be run in a browser.
59//!
60//! A full description of the component model is out of scope for this crate's
61//! documentation but it suffices to say that [WASI], and this crate, are
62//! intended to target components. Components use core WebAssembly modules as an
63//! important technical detail, but the final output of this crate is intended
64//! to be a component.
65//!
66//! # What are generated bindings?
67//!
68//! Above it was seen that [WASI] is defined with [WIT]. These programmatic
69//! descriptions of [WASI] APIs are not suitable for use directly in Rust,
70//! however these descriptions define how Rust can use them. Each [WIT] function
71//! has a defined meaning in core WebAssembly via the [Canonical ABI]. This is a
72//! lower level than most users want to operate at, however, so the generated
73//! bindings in this crate serve as the bridge.
74//!
75//! More specifically the generated functions in this crate take the [Canonical
76//! ABI] format of [WIT] functions and provide idiomatic Rust functions to call.
77//! For example the [`wasi:cli/environment`] definition includes:
78//!
79//! ```wit
80//! interface environment {
81//! // ...
82//! get-environment: func() -> list<tuple<string, string>>;
83//! // ...
84//! }
85//! ```
86//!
87//! This corresponds to
88//! [`wasi::cli::environment::get_environment`](crate::cli::environment::get_environment).
89//!
90//! Bindings are pre-generated in this crate with the [`wit-bindgen`] tool. You
91//! can also generate your own bindings with [`wit-bindgen`] and [WASI] [WIT]
92//! files too, but that's not covered by this crate.
93//!
94//! # WASI Today and `wasi_snapshot_preview1`
95//!
96//! This crate is based on the 0.2.0 version of [WASI] APIs. This version of
97//! [WASI] was declared "phase 3" (suitable for general use and testing) in
98//! January of 2024. Prior to this 0.2.0 "preview2" release of [WASI] there was
99//! `wasi_snapshot_preview1`. This previous "preview1" release of [WASI] was
100//! circa 2019 and was the initial vision for [WASI] as a standard. Development
101//! of [WASI] migrated to the [Component Model] in the meantime.
102//!
103//! This means that the old `wasi_snapshot_preview1` interfaces are no longer
104//! provided by this crate because [WASI] is no longer defined by those
105//! interfaces. This includes the historical `*.witx` format which has now been
106//! sueprseded. Note that the 0.11.x release series of this crate contains
107//! bindings to the historical `wasi_snapshot_preview1` APIs if you're
108//! interested in using them.
109//!
110//! # Crate Organization
111//!
112//! This crate is currently entirely generated by [`wit-bindgen`] which has the
113//! following structure:
114//!
115//! * Each [WIT] package with bindings corresponds to a top-level module. For
116//! example [`wasi:random`] can be found in the [`random`] module.
117//! * Each [WIT] interface then corresponds to a submodule of its package's
118//! module. For example [`wasi:random/insecure`] can be found in the
119//! [`random::insecure`] module.
120//! * Each [WIT] function has a Rust function with an idiomatic signature.
121//! module. For example [`random::insecure::get_insecure_random_u64`].
122//!
123//! Note that [WIT] documentation is rendered as rustdoc documentation in these
124//! APIs as well.
125//!
126//! # Using this Crate
127//!
128//! This crate is intended to be easiest to use with a future
129//! `wasm32-wasip2` target added to the Rust compiler. In the meantime
130//! it's recommended to use the `wasm32-wasip1` target instead:
131//!
132//! ```sh
133//! $ cargo build --target wasm32-wasip1
134//! ```
135//!
136//! Note that the output of the `wasm32-wasip1` target is a core wasm module, not
137//! a component, so to turn it into a component you can use the [`wasm-tools`]
138//! CLI in combination with an "adapter module" for the `wasi_snapshot_preview1`
139//! APIs that the Rust standard library uses (example adapters can be found on
140//! [Wasmtime's release page][adapters] as
141//! [`wasi_snapshot_preview1.command.wasm`] for example)
142//!
143//! ```sh
144//! $ wasm-tools component new ./target/wasm32-wasip1/debug/my-app.wasm \
145//! --adapt ./wasi_snapshot_preview1.command.wasm \
146//! -o my-component.wasm
147//! ```
148//!
149//! ## Export Macros
150//!
151//! In addition to providing bindings for imports this crate also provides
152//! macros to export the `wasi:cli/run` and `wasi:http/proxy` worlds, see their
153//! respective documentation for more information:
154//!
155//! - [`wasi::cli::command::export!`](crate::cli::command::export)
156//! - [`wasi::http::proxy::export!`](crate::http::proxy::export)
157//!
158//! [worlds]: https://component-model.bytecodealliance.org/design/worlds.html
159//! [`wasi:cli/command`]: https://github.com/WebAssembly/wasi-cli/
160//! [`wasi:http/proxy`]: https://github.com/WebAssembly/wasi-http
161//! [`wasi:cli/stdio`]: https://github.com/WebAssembly/wasi-cli/blob/main/wit/stdio.wit
162//! [`wit-bindgen`]: https://github.com/bytecodealliance/wit-bindgen/
163//! [Component Model]: https://component-model.bytecodealliance.org/
164//! [WIT]: https://component-model.bytecodealliance.org/design/wit.html
165//! [standard WebAssembly modules]: https://webassembly.github.io/spec/
166//! [Wasmtime]: https://github.com/bytecodealliance/wasmtime
167//! [jco]: https://github.com/bytecodealliance/jco
168//! [Canonical ABI]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md
169//! [`wasi:cli/environment`]: https://github.com/WebAssembly/wasi-cli/blob/main/wit/environment.wit
170//! [`wasi:random`]: https://github.com/WebAssembly/wasi-random
171//! [`wasi:random/insecure`]: https://github.com/WebAssembly/wasi-random/blob/main/wit/insecure.wit
172//! [`wasm-tools`]: https://github.com/bytecodealliance/wasm-tools
173//! [adapters]: https://github.com/bytecodealliance/wasmtime/releases
174//! [`wasi_snapshot_preview1.command.wasm`]: https://github.com/bytecodealliance/wasmtime/releases/download/v17.0.0/wasi_snapshot_preview1.command.wasm
175
176#![no_std]
177
178#[cfg(feature = "std")]
179extern crate std;
180
181pub mod ext;
182
183// These modules are all auto-generated by `./ci/regenerate.sh`
184mod bindings;
185#[allow(unused_imports)]
186mod command;
187#[allow(unused_imports)]
188mod proxy;
189
190// generated bindings start with the package namespace, which in this case is
191// `wasi`, but the crate is already called wasi, so lift everything up one level
192// to the root of this crate.
193pub use bindings::wasi::*;
194
195// Expand the `cli` and `http` modules with `export!` macros for the
196// command/proxy worlds, but also retain all the contents defined in the
197// `bindings` module as well.
198pub mod cli {
199 pub use super::bindings::wasi::cli::*;
200
201 pub mod command {
202 /// Generate an exported instance of the `wasi:cli/command` world.
203 ///
204 /// This macro generate the `#[no_mangle]` functions necessary to
205 /// export this interface. It takes an argument which is a type that
206 /// must implement the
207 /// [`exports::cli::run::Guest`](crate::exports::cli::run::Guest)
208 /// trait.
209 ///
210 /// ```
211 /// struct MyCliRunner;
212 ///
213 /// impl wasi::exports::cli::run::Guest for MyCliRunner {
214 /// fn run() -> Result<(), ()> {
215 /// // ...
216 /// # panic!();
217 /// }
218 /// }
219 ///
220 /// wasi::cli::command::export!(MyCliRunner);
221 /// ```
222 ///
223 /// ## Compatibility with `wasm32-wasip1` targets
224 ///
225 /// This macro is not compatible with `wasm32-wasip1` `bin` targets
226 /// which instead use a `fn main()` with the
227 /// `wasi_snapshot_preview1.command.wasm` adapter. This macro _can_ be
228 /// used with the `reactor` or `proxy` adapters.
229 ///
230 /// <!--
231 /// The marker above hides the generated documentation by wit-bindgen for this
232 /// macro.
233 /// -->
234 #[doc(inline)]
235 pub use crate::command::_export_command as export;
236 }
237}
238
239pub mod http {
240 pub use super::bindings::wasi::http::*;
241
242 pub mod proxy {
243 /// Generate an exported instance of the `wasi:http/proxy` world.
244 ///
245 /// This macro will generate `#[no_mangle]` functions as necessary to
246 /// export an implementation of the
247 /// [`exports::http::incoming_handler::Guest`](crate::exports::http::incoming_handler::Guest)
248 /// trait. This macro takes
249 /// an argument which is a type that implements this trait:
250 ///
251 /// ```
252 /// use wasi::http::types::{IncomingRequest, ResponseOutparam};
253 ///
254 /// struct MyIncomingHandler;
255 ///
256 /// impl wasi::exports::http::incoming_handler::Guest for MyIncomingHandler {
257 /// fn handle(request: IncomingRequest, response_out: ResponseOutparam) {
258 /// // ...
259 /// # panic!();
260 /// }
261 /// }
262 ///
263 /// wasi::http::proxy::export!(MyIncomingHandler);
264 /// ```
265 ///
266 /// <!--
267 /// The marker above hides the generated documentation by wit-bindgen
268 /// for this macro.
269 /// -->
270 #[doc(inline)]
271 pub use crate::proxy::_export_proxy as export;
272 }
273}
274
275pub mod exports {
276 // This is required by the `export!` macros of this crate which assume that
277 // the types it's referring to show up as `exports::wasi::...`.
278 //
279 // This isn't part of the public interface, though, so hide this.
280 #[doc(hidden)]
281 pub mod wasi {
282 pub use crate::command::exports::wasi::*;
283 pub use crate::proxy::exports::wasi::*;
284 }
285
286 // These are the restructured public interface of this crate.
287 pub use crate::command::exports::wasi::cli;
288 pub use crate::proxy::exports::wasi::http;
289}
290
291// These macros are used by recursive invocations of the macro, but they're
292// `#[doc(hidden)]` as it's not part of the public interface.
293#[doc(hidden)]
294pub use crate::command::_export_command;
295#[doc(hidden)]
296pub use crate::proxy::_export_proxy;