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, result: Option, } #[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 { imports: I, exports: E, } fn instantiate( wasm: &str, add_imports: impl FnOnce(&mut Linker>) -> Result<()>, mk_exports: impl FnOnce( &mut Store>, &Module, &mut Linker>, ) -> Result<(T, Instance)>, ) -> Result<(T, Store>)> { 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 { // 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) }