use wit_component::{ComponentEncoder, StringEncoding, embed_component_metadata};
use wit_parser::{Resolve, UnresolvedPackageGroup};
use super::error::Wasip2Error;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Wasip2World {
CliCommand,
HttpProxy,
}
impl Wasip2World {
pub fn wit_name(self) -> &'static str {
match self {
Wasip2World::CliCommand => "wasi:cli/command",
Wasip2World::HttpProxy => "wasi:http/proxy",
}
}
pub(super) fn local_name(self) -> &'static str {
match self {
Wasip2World::CliCommand => "command",
Wasip2World::HttpProxy => "http-proxy",
}
}
}
pub fn compile_to_component(
core_wasm: &[u8],
world: Wasip2World,
) -> Result<(Vec<u8>, String), Wasip2Error> {
if matches!(world, Wasip2World::HttpProxy) {
return Err(Wasip2Error::NotImplemented(
"world `wasi:http/proxy` (Phase 3) is not wired in 0.18 — \
use `--world wasi:cli/command` for the long-running process \
shape, or wait for the deliberate Phase 3 / 0.19+ design"
.to_string(),
));
}
let mut resolve = Resolve::default();
super::wasi_bundle::push_wasi_packages(&mut resolve)?;
let wit_source = super::wit::emit_world_wit(world);
let unresolved = UnresolvedPackageGroup::parse("aver-generated.wit", &wit_source)
.map_err(|e| Wasip2Error::Wrap(format!("WIT parse failed for generated package: {e}")))?;
let pkg_id = resolve
.push_group(unresolved)
.map_err(|e| Wasip2Error::Wrap(format!("push aver:user package into Resolve: {e}")))?;
let world_id = resolve
.select_world(&[pkg_id], Some(world.local_name()))
.map_err(|e| {
Wasip2Error::Wrap(format!(
"select world `{}` in generated package: {e}",
world.local_name()
))
})?;
let mut core = core_wasm.to_vec();
embed_component_metadata(&mut core, &resolve, world_id, StringEncoding::UTF8)
.map_err(|e| Wasip2Error::Wrap(format!("embed component-type metadata: {e}")))?;
let component = ComponentEncoder::default()
.module(&core)
.map_err(|e| Wasip2Error::Wrap(format!("ComponentEncoder::module rejected core: {e}")))?
.validate(true)
.encode()
.map_err(|e| Wasip2Error::Wrap(format!("ComponentEncoder::encode failed: {e}")))?;
Ok((component, wit_source))
}