feat: add __wasm/rust-wasm-plugins-examples/

This commit is contained in:
2025-07-12 13:22:38 +08:00
parent f2fd57c342
commit e45d14498c
19 changed files with 3195 additions and 11 deletions

View File

@@ -0,0 +1,3 @@
#![allow(missing_docs)]
wasmtime::component::bindgen!(in "../assets/wit/acme-plugins.wit");

View File

@@ -0,0 +1,41 @@
use super::bindings::acme::plugins::host;
use wasmtime_wasi::{IoView, ResourceTable, WasiCtx, WasiCtxBuilder, WasiView};
//
// Host
//
/// Plugins host.
pub struct Host {
wasi: WasiCtx,
resources: ResourceTable,
}
impl Host {
/// Constructor.
pub fn new() -> Self {
let wasi = WasiCtxBuilder::new().inherit_stdout().build();
Self { wasi, resources: ResourceTable::new() }
}
}
// We need to implement WasiView for wasmtime_wasi::add_to_linker_sync
impl WasiView for Host {
fn ctx(&mut self) -> &mut WasiCtx {
&mut self.wasi
}
}
impl IoView for Host {
fn table(&mut self) -> &mut ResourceTable {
&mut self.resources
}
}
// Our exposed Host functions
impl host::Host for Host {
fn log(&mut self, message: String) {
println!("log: {}", message);
}
}

View File

@@ -0,0 +1,11 @@
mod bindings;
mod host;
mod prettify;
use prettify::*;
pub fn main() {
let mut prettify = Prettify::new("target/wasm32-wasip2/release/plugin.wasm").unwrap();
let r = prettify.prettify("We will prettify this with a plugin").unwrap();
println!("{}", r);
}

View File

@@ -0,0 +1,55 @@
use super::{bindings, host::*};
use {
anyhow::Context,
std::path,
wasmtime::{component::*, Engine, Store},
};
//
// Prettify
//
/// Prettify plugin.
pub struct Prettify {
store: Store<Host>,
prettify: bindings::Prettify,
}
// Wasmtime uses Anyhow for most of its errors
// But you could potentially wrap it in your own "PluginError" or similar using .map_err
// For this example we used .context
impl Prettify {
/// Constructor.
pub fn new<PathT>(module: PathT) -> Result<Self, anyhow::Error>
where
PathT: AsRef<path::Path>,
{
let engine = Engine::default();
// Component
let component = Component::from_file(&engine, module).context("load component")?;
// Linker
let mut linker = Linker::new(&engine);
wasmtime_wasi::add_to_linker_sync(&mut linker).context("link WASI")?;
bindings::Prettify::add_to_linker(&mut linker, |state: &mut Host| state).context("link plugin host")?;
// Store
let mut store = Store::new(&engine, Host::new());
// Bindings
let prettify =
bindings::Prettify::instantiate(&mut store, &component, &linker).context("instantiate bindings")?;
Ok(Self { store, prettify })
}
// We'll create convenience wrappers to make calling functions ergonomic:
/// Prettify.
pub fn prettify(&mut self, name: &str) -> Result<String, anyhow::Error> {
self.prettify.acme_plugins_prettify_plugin().call_prettify(&mut self.store, name)
}
}