Expand description
Raw API bindings to the WebAssembly System Interface p3 (WASIp3)
This crate provides Rust API bindings to the imports of WASIp3 worlds such as:
This crate is procedurally generated with the wit-bindgen
bindings
generator. Note that generated code is published to crates.io to slim this
crate down in terms of build dependencies and resources.
§What is WASIp3?
WASIp3 is a set of APIs defined for the WebAssembly Component Model to
help components interact with the outside world. Core WebAssembly has no
intrinsic ability to access the host, for example println!
don’t work, but
WASIp3 defines how to do so with the wasi:cli/stdio
package.
WASIp3 is defined by an IDL called WIT using files that have the extension
*.wit
. WASIp3 and WIT are themselves then both defined in terms of the
Component Model in terms of types available and base semantics for APIs.
WASIp3 defines a number of standard “worlds” which are a description of a
what a WebAssembly component can import from an embedding and must export to
an embedding. An example world is wasi:cli/command
which is a world for
running CLI applications. This world provides basic system utilities such as
clocks, a filesystem, CLI arguments, etc. The one required export is a main
function.
The purpose of this crate is to provide pregenerated bindings to access WASIp3-defined imports available to components.
§What is a Component?
An important aspect of WASIp3 is that it is defined in terms of the Component Model. The Component Model is a proposal for WebAssembly which is a new format for wasm binaries, a component. A component contains “core” WebAssembly modules (which are standard WebAssembly modules) but also has the ability to do more:
- A component can contain multiple core WebAssembly modules.
- Types used with component imports and exports are more comprehensive than
core WebAssembly. Core WebAssembly provides integers and floats, for
example, and components build on this and add strings, records (aka a Rust
struct
), variants (aka a Rustenum
), and resources (think a file descriptor on Unix). - A component provides procedural instructions of how to instantiate its internal core WebAssembly modules with the imports it has.
A full description of the component model is out of scope for this crate’s documentation but it suffices to say that WASIp3, and this crate, are intended to target components. Components use core WebAssembly modules as an important technical detail, but the final output of this crate is intended to be a component.
§What are generated bindings?
Above it was seen that WASIp3 is defined with WIT. These programmatic descriptions of WASIp3 APIs are not suitable for use directly in Rust, however these descriptions define how Rust can use them. Each WIT function has a defined meaning in core WebAssembly via the Canonical ABI. This is a lower level than most users want to operate at, however, so the generated bindings in this crate serve as the bridge.
More specifically the generated functions in this crate take the Canonical
ABI format of WIT functions and provide idiomatic Rust functions to call.
For example the wasi:cli/environment
definition includes:
interface environment {
// ...
get-environment: func() -> list<tuple<string, string>>;
// ...
}
This corresponds to
wasi::cli::environment::get_environment
.
Bindings are pre-generated in this crate with the wit-bindgen
tool. You
can also generate your own bindings with wit-bindgen
and WASIp3 WIT
files too, but that’s not covered by this crate.
§WASIp3, WASIp2, and WASIp1
The WASIp3 version of the WASI standard is not yet complete nor stable. It is under development and this crate represents a snapshot in time of what the APIs may eventually look like.
Users looking for stability should use WASIp2 (the wasip2
crate) instead.
Users looking for core wasm, not components, should use the wasip1
crate.
§Crate Organization
This crate is currently entirely generated by wit-bindgen
which has the
following structure:
- Each WIT package with bindings corresponds to a top-level module. For
example
wasi:random
can be found in therandom
module. - Each WIT interface then corresponds to a submodule of its package’s
module. For example
wasi:random/insecure
can be found in therandom::insecure
module. - Each WIT function has a Rust function with an idiomatic signature.
module. For example
random::insecure::get_insecure_random_u64
.
Note that WIT documentation is rendered as rustdoc documentation in these APIs as well.
§Using this Crate
This crate is intended to be used with the wasm32-wasip2
target to the
Rust compiler. You can compile your code as:
$ cargo build --target wasm32-wasip2
Eventually a wasm32-wasip3
target will be added to the Rust compiler but
in the meantime the wasm32-wasip2
target suffices. Using a WASIp2 target
means that the standard library will use WASIp2, but users of this crate
will use WASIp3.
§Export Macros
In addition to providing bindings for imports this crate also provides
macros to export the wasi:cli/run
and wasi:http/proxy
worlds, see their
respective documentation for more information:
Re-exports§
pub use wit_bindgen;