Path: blob/main/crates/wasi-config/src/lib.rs
3070 views
//! # Wasmtime's [wasi-config] Implementation1//!2//! This crate provides a Wasmtime host implementation of the [wasi-config]3//! API. With this crate, the runtime can run components that call APIs in4//! [wasi-config] and provide configuration variables for the component.5//!6//! # Examples7//!8//! The usage of this crate is very similar to other WASI API implementations9//! such as [wasi:cli] and [wasi:http].10//!11//! A common scenario is getting runtime-passed configurations in a [wasi:cli]12//! component. A standalone example of doing all this looks like:13//!14//! ```15//! use wasmtime::{16//! component::{Linker, ResourceTable},17//! Engine, Result, Store,18//! };19//! use wasmtime_wasi::{WasiCtx, WasiCtxView, WasiView};20//! use wasmtime_wasi_config::{WasiConfig, WasiConfigVariables};21//!22//! #[tokio::main]23//! async fn main() -> Result<()> {24//! let engine = Engine::default();25//!26//! let mut store = Store::new(&engine, Ctx {27//! table: ResourceTable::new(),28//! wasi_ctx: WasiCtx::builder().build(),29//! wasi_config_vars: WasiConfigVariables::from_iter(vec![30//! ("config_key1", "value1"),31//! ("config_key2", "value2"),32//! ]),33//! });34//!35//! let mut linker = Linker::<Ctx>::new(&engine);36//! wasmtime_wasi::p2::add_to_linker_async(&mut linker)?;37//! // add `wasi-config` world's interfaces to the linker38//! wasmtime_wasi_config::add_to_linker(&mut linker, |h: &mut Ctx| {39//! WasiConfig::from(&h.wasi_config_vars)40//! })?;41//!42//! // ... use `linker` to instantiate within `store` ...43//!44//! Ok(())45//! }46//!47//! struct Ctx {48//! table: ResourceTable,49//! wasi_ctx: WasiCtx,50//! wasi_config_vars: WasiConfigVariables,51//! }52//!53//! impl WasiView for Ctx {54//! fn ctx(&mut self) -> WasiCtxView<'_> {55//! WasiCtxView { ctx: &mut self.wasi_ctx, table: &mut self.table }56//! }57//! }58//! ```59//!60//! [wasi-config]: https://github.com/WebAssembly/wasi-config61//! [wasi:cli]: https://docs.rs/wasmtime-wasi/latest62//! [wasi:http]: https://docs.rs/wasmtime-wasi-http/latest6364#![deny(missing_docs)]6566use std::collections::HashMap;67use wasmtime::Result;68use wasmtime::component::HasData;6970mod gen_ {71wasmtime::component::bindgen!({72path: "wit",73world: "wasi:config/imports",74imports: { default: trappable },75});76}77use self::gen_::wasi::config::store as generated;7879/// Capture the state necessary for use in the `wasi-config` API implementation.80#[derive(Default)]81pub struct WasiConfigVariables(HashMap<String, String>);8283impl<S: Into<String>> FromIterator<(S, S)> for WasiConfigVariables {84fn from_iter<I: IntoIterator<Item = (S, S)>>(iter: I) -> Self {85Self(86iter.into_iter()87.map(|(k, v)| (k.into(), v.into()))88.collect(),89)90}91}9293impl WasiConfigVariables {94/// Create a new runtime configuration.95pub fn new() -> Self {96Default::default()97}9899/// Insert a key-value pair into the configuration map.100pub fn insert(&mut self, key: impl Into<String>, value: impl Into<String>) -> &mut Self {101self.0.insert(key.into(), value.into());102self103}104}105106/// A wrapper capturing the needed internal `wasi-config` state.107pub struct WasiConfig<'a> {108vars: &'a WasiConfigVariables,109}110111impl<'a> From<&'a WasiConfigVariables> for WasiConfig<'a> {112fn from(vars: &'a WasiConfigVariables) -> Self {113Self { vars }114}115}116117impl<'a> WasiConfig<'a> {118/// Create a new view into the `wasi-config` state.119pub fn new(vars: &'a WasiConfigVariables) -> Self {120Self { vars }121}122}123124impl generated::Host for WasiConfig<'_> {125fn get(&mut self, key: String) -> Result<Result<Option<String>, generated::Error>> {126Ok(Ok(self.vars.0.get(&key).map(|s| s.to_owned())))127}128129fn get_all(&mut self) -> Result<Result<Vec<(String, String)>, generated::Error>> {130Ok(Ok(self131.vars132.0133.iter()134.map(|(k, v)| (k.to_string(), v.to_string()))135.collect()))136}137}138139/// Add all the `wasi-config` world's interfaces to a [`wasmtime::component::Linker`].140pub fn add_to_linker<T: 'static>(141l: &mut wasmtime::component::Linker<T>,142f: fn(&mut T) -> WasiConfig<'_>,143) -> Result<()> {144generated::add_to_linker::<T, HasWasiConfig>(l, f)?;145Ok(())146}147148struct HasWasiConfig;149150impl HasData for HasWasiConfig {151type Data<'a> = WasiConfig<'a>;152}153154155