//! # Wasmtime's wasi-io Implementation1//!2//! This crate provides a Wasmtime host implementation of the WASI 0.2 (aka3//! WASIp2 aka Preview 2) wasi-io package. The host implementation is4//! abstract: it is exposed as a set of traits which other crates provide5//! impls of.6//!7//! The wasi-io package is the foundation which defines how WASI programs8//! interact with the scheduler. It provides the `pollable`, `input-stream`,9//! and `output-stream` Component Model resources, which other packages10//! (including wasi-filesystem, wasi-sockets, wasi-cli, and wasi-http)11//! expose as the standard way to wait for readiness, and asynchronously read12//! and write to streams.13//!14//! This crate is designed to have no unnecessary dependencies and, in15//! particular, to be #![no_std]. For an example no_std embedding, see16//! [`/examples/min-platform`](https://github.com/bytecodealliance/wasmtime/tree/main/examples/min-platform)17//! at the root of the wasmtime repo.1819#![no_std]2021extern crate alloc;22#[cfg(feature = "std")]23#[macro_use]24extern crate std;2526pub mod bindings;27mod impls;28pub mod poll;29pub mod streams;3031#[doc(no_inline)]32pub use async_trait::async_trait;3334#[doc(no_inline)]35pub use ::bytes;3637use alloc::boxed::Box;38use wasmtime::component::{HasData, ResourceTable};3940/// A trait which provides access to the [`ResourceTable`] inside the41/// embedder's `T` of [`Store<T>`][`Store`].42///43/// This crate's WASI Host implementations depend on the contents of44/// [`ResourceTable`]. The `T` type [`Store<T>`][`Store`] is defined in each45/// embedding of Wasmtime. These implementations is connected to the46/// [`Linker<T>`][`Linker`] by the47/// [`add_to_linker_async`] function.48///49/// # Example50///51/// ```52/// use wasmtime::{Config, Engine};53/// use wasmtime::component::{ResourceTable, Linker};54/// use wasmtime_wasi_io::{IoView, add_to_linker_async};55///56/// struct MyState {57/// table: ResourceTable,58/// }59///60/// impl IoView for MyState {61/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }62/// }63/// let mut config = Config::new();64/// config.async_support(true);65/// let engine = Engine::new(&config).unwrap();66/// let mut linker: Linker<MyState> = Linker::new(&engine);67/// add_to_linker_async(&mut linker).unwrap();68/// ```69/// [`Store`]: wasmtime::Store70/// [`Linker`]: wasmtime::component::Linker71/// [`ResourceTable`]: wasmtime::component::ResourceTable72///73pub trait IoView {74/// Yields mutable access to the internal resource management that this75/// context contains.76///77/// Embedders can add custom resources to this table as well to give78/// resources to wasm as well.79fn table(&mut self) -> &mut ResourceTable;80}8182impl<T: ?Sized + IoView> IoView for &mut T {83fn table(&mut self) -> &mut ResourceTable {84T::table(self)85}86}87impl<T: ?Sized + IoView> IoView for Box<T> {88fn table(&mut self) -> &mut ResourceTable {89T::table(self)90}91}9293/// Add the wasi-io host implementation from this crate into the `linker`94/// provided.95///96/// This function will add the `async` variant of all interfaces into the97/// [`Linker`] provided. By `async` this means that this function is only98/// compatible with [`Config::async_support(true)`][async]. For embeddings99/// with async support disabled, you'll need to use other crates, such as the100/// [`wasmtime-wasi`] crate, which provides an [`add_to_linker_sync`] that101/// includes an appropriate wasi-io implementation based on this crate's.102///103/// This function will add all interfaces implemented by this crate to the104/// [`Linker`], which corresponds to the `wasi:io/imports` world supported by105/// this crate.106///107/// [async]: wasmtime::Config::async_support108/// [`Linker`]: wasmtime::component::Linker109/// [`wasmtime-wasi`]: https://crates.io/crates/wasmtime-wasi110/// [`add_to_linker_sync`]: https://docs.rs/wasmtime-wasi/latest/wasmtime_wasi/fn.add_to_linker_sync.html111///112///113/// # Example114///115/// ```116/// use wasmtime::{Engine, Result, Store, Config};117/// use wasmtime::component::{ResourceTable, Linker};118/// use wasmtime_wasi_io::IoView;119///120/// fn main() -> Result<()> {121/// let mut config = Config::new();122/// config.async_support(true);123/// let engine = Engine::new(&config)?;124///125/// let mut linker = Linker::<MyState>::new(&engine);126/// wasmtime_wasi_io::add_to_linker_async(&mut linker)?;127/// // ... add any further functionality to `linker` if desired ...128///129/// let mut store = Store::new(130/// &engine,131/// MyState {132/// table: ResourceTable::new(),133/// },134/// );135///136/// // ... use `linker` to instantiate within `store` ...137///138/// Ok(())139/// }140///141/// struct MyState {142/// table: ResourceTable,143/// }144///145/// impl IoView for MyState {146/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }147/// }148/// ```149pub fn add_to_linker_async<T: IoView + Send + 'static>(150l: &mut wasmtime::component::Linker<T>,151) -> wasmtime::Result<()> {152crate::bindings::wasi::io::error::add_to_linker::<T, WasiIo>(l, T::table)?;153crate::bindings::wasi::io::poll::add_to_linker::<T, WasiIo>(l, T::table)?;154crate::bindings::wasi::io::streams::add_to_linker::<T, WasiIo>(l, T::table)?;155Ok(())156}157158struct WasiIo;159160impl HasData for WasiIo {161type Data<'a> = &'a mut ResourceTable;162}163164165