extism PDK(Rust) で plug-in (wasm)を作成し、extism SDK(Rust) で呼び出す
extism 公式レポジトリ
ユニバーサルプラグインシステムを謳っている(?)OSS
PDK(Plugin Development Kit)を使い plug-in(wasm)を作成し SDK(Software Development Kit)から call する
PDK は
Rust, AssemblyScript, Go, C/C++, Haskell, Zig
SDK は
Go, Ruby, Python, Node, Rust, C, C++, OCaml, Haskell, PHP, Elixir/Erlang, .NET, Java, Zig
が対応している
extism-cli のインストール
sh <(curl https://raw.githubusercontent.com/extism/cli/main/install.sh) /usr/local/bin
extism install latest
cargo new extism_pdk_rust_sample --lib
Cargo.toml に追記
[lib]
crate_type = ["cdylib"]
[dependencies]
extism-pdk = "0.3.4"
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.106"
lib.rs を編集
#[derive(serde::Deserialize)]
struct Multiply {
a: u32,
b: u32,
}
#[derive(serde::Serialize)]
struct Product {
product: u32,
}
#[plugin_fn]
pub fn multiply(Json(mul): Json<Multiply>) -> FnResult<Json<Product>> {
let product = Product { product: mul.a * mul.b };
Ok(Json(product))
}
ビルド
rustup target add wasm32-unknown-unknown
cargo build --release --target wasm32-unknown-unknown
extism-cli を使ってテスト
extism call ./target/wasm32-unknown-unknown/release/extism_pdk_rust_sample.wasm multiply --input '{"a": 2, "b": 3}' --config thing=i_hope_this_flag_become_optional
cargo new extism_sdk_rust_sample
Cargo.toml に追記
[dependencies]
extism = "0.5.0"
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.106"
main.rs を編集
fn sdk_sample() {
let wasm = include_bytes!("../../extism_pdk_rust_sample/target/wasm32-unknown-unknown/release/extism_pdk_rust_sample.wasm");
let context = Context::new();
// ignore official document
let mut plugin = Plugin::new(&context, wasm, [], false).unwrap();
let data = plugin.call("multiply", "{\"a\": 2, \"b\": 3}").unwrap();
// bite to string
let data_str = std::str::from_utf8(&data).expect("Failed to convert to string");
// string to json
let parsed: Value = serde_json::from_str(data_str).expect("Failed to parse JSON");
// json to int
if let Some(count) = parsed["product"].as_i64() {
println!("product: {}", count);
} else {
println!("Failed to retrieve 'product' value");
}
}
fn main() {
sdk_sample();
}
実行
cargo run
product: 6