use anyhow::{Context as AnyhowContext, Result};
use bytes::Bytes;
use wasmtime::{Config, Engine, component::Component, error::Context};
use wit_component::ComponentEncoder;
static WASI_ADAPTER: &[u8] = include_bytes!("../res/wasi_snapshot_preview1.reactor.wasm");
#[derive(Clone)]
pub struct Image {
engine: Engine,
component: Component,
}
impl Image {
pub fn new(wasm_binary: Bytes) -> Result<Self> {
let mut config = Config::new();
config.wasm_component_model(true);
let engine = Engine::new(&config).context("Failed to create WASM engine")?;
let component_binary = ComponentEncoder::default()
.module(wasm_binary.as_ref())
.context("Failed to parse WASM module")?
.validate(true)
.adapter("wasi_snapshot_preview1", WASI_ADAPTER)
.context("Failed to add WASI adapter")?
.encode()
.context("Failed to encode WASM component")?;
let component = Component::from_binary(&engine, &component_binary)
.context("Failed to compile WASM component")?;
Ok(Self { engine, component })
}
pub fn from_component(component_binary: Bytes) -> Result<Self> {
let mut config = Config::new();
config.wasm_component_model(true);
let engine = Engine::new(&config).context("Failed to create WASM engine")?;
let component = Component::from_binary(&engine, component_binary.as_ref())
.context("Failed to compile WASM component")?;
Ok(Self { engine, component })
}
pub(crate) fn engine(&self) -> &Engine {
&self.engine
}
pub(crate) fn component(&self) -> &Component {
&self.component
}
}
impl std::fmt::Debug for Image {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Image").finish()
}
}