Files
simple-rust-tests/__wasm/wit-bindgen-sample/container/src/main.rs
2022-07-17 10:48:23 +08:00

108 lines
2.9 KiB
Rust

use anyhow::Result;
use serde::{Deserialize, Serialize};
use wasmtime::{Config, Engine, Instance, Linker, Module, Store};
use container::*;
wit_bindgen_wasmtime::export!("../container.wit");
#[derive(Clone, Debug, Serialize, Deserialize)]
struct FetchResult {
error: Option<String>,
result: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
struct JsResult {
message: String,
}
#[derive(Default)]
pub struct MyContainer;
impl Container for MyContainer {
fn fetch(&mut self, s: &str) -> String {
// // format!("FETCHED: {}", s)
// let r = "{\"result\":\"{}\"}".into();
// println!(">>>> {}", r);
// r
serde_json::to_string(&FetchResult {
error: None,
result: Some(serde_json::to_string(&JsResult {
message: format!("inputs: {}", s),
}).expect("to json failed.1")),
}).expect("to json failed.2")
}
}
wit_bindgen_wasmtime::import!("../exports.wit");
fn main() -> Result<()> {
use exports::*;
let wasm = "../engine/target/wasm32-unknown-unknown/debug/engine.wasm";
let (exports, mut store) = instantiate(
wasm,
|linker| container::add_to_linker(linker, |cx| -> &mut MyContainer { &mut cx.imports }),
|store, module, linker| Exports::instantiate(store, module, linker, |cx| &mut cx.exports),
)?;
let a = exports.eval_javascript(&mut store, r##"
function hi(name) { return "hi: " + name; }
let a = [];
a.push(fetch('https://www.google.com/'));
for (let i = 0; i < 3; i++) { a.push(i); }
a.push({
id: 1, name: 'hatter'
});
a.push(hi('001'));
a.push(hi('002'));
// JSON.stringify(a)
a
"##);
match a {
Ok(a) => println!("Hello, world! {:?}", a),
Err(e) => println!("ERROR: {}", e),
}
Ok(())
}
struct Context<I, E> {
imports: I,
exports: E,
}
fn instantiate<I: Default, E: Default, T>(
wasm: &str,
add_imports: impl FnOnce(&mut Linker<Context<I, E>>) -> Result<()>,
mk_exports: impl FnOnce(
&mut Store<Context<I, E>>,
&Module,
&mut Linker<Context<I, E>>,
) -> Result<(T, Instance)>,
) -> Result<(T, Store<Context<I, E>>)> {
let engine = Engine::new(&default_config()?)?;
let module = Module::from_file(&engine, wasm)?;
let mut linker = Linker::new(&engine);
add_imports(&mut linker)?;
let mut store = Store::new(
&engine,
Context {
imports: I::default(),
exports: E::default(),
},
);
let (exports, _instance) = mk_exports(&mut store, &module, &mut linker)?;
Ok((exports, store))
}
fn default_config() -> Result<Config> {
// Create an engine with caching enabled to assist with iteration in this project.
let mut config = Config::new();
config.cache_config_load_default()?;
config.wasm_backtrace_details(wasmtime::WasmBacktraceDetails::Enable);
Ok(config)
}