deterministic-wasi-ctx 4.0.7

A wasmtime-wasi WasiCtx implementation that is fully deterministic
Documentation
use anyhow::Result;
use std::{fs, path::Path};
use wasmtime::*;
use wasmtime_wasi::WasiCtxBuilder;

pub fn test_instance<Params, Results, F>(module_name: &str, testcase: F) -> Result<()>
where
    Params: WasmParams,
    Results: WasmResults,
    F: Fn(Box<dyn FnOnce(&str, Params) -> wasmtime::Result<Results>>) -> wasmtime::Result<()>,
{
    let module_path = Path::new("../../target/wasm32-wasip1/debug").join(module_name);
    let bytes = fs::read(module_path)?;
    Ok(test_instance_with_bytes(&bytes, testcase)?)
}

pub fn test_instance_with_bytes<Params, Results, F>(
    bytes: &[u8],
    testcase: F,
) -> wasmtime::Result<()>
where
    Params: WasmParams,
    Results: WasmResults,
    F: Fn(Box<dyn FnOnce(&str, Params) -> wasmtime::Result<Results>>) -> wasmtime::Result<()>,
{
    let engine = Engine::default();
    let module = Module::new(&engine, bytes)?;

    let mut wasi_builder = WasiCtxBuilder::new();
    deterministic_wasi_ctx::add_determinism_to_wasi_ctx_builder(&mut wasi_builder);
    let wasi = wasi_builder.build_p1();

    let mut linker = Linker::new(&engine);
    wasmtime_wasi::p1::add_to_linker_sync(&mut linker, |s| s)?;
    deterministic_wasi_ctx::replace_scheduling_functions(&mut linker)?;

    let mut store = Store::new(&engine, wasi);
    let instance = linker.instantiate(&mut store, &module)?;

    testcase(Box::new(move |func_name, params| {
        let answer = instance
            .get_func(&mut store, func_name)
            .unwrap_or_else(|| panic!("`{}` was not an exported function", func_name));
        let answer = answer.typed::<Params, Results>(&store)?;
        answer.call(&mut store, params)
    }))?;

    Ok(())
}