use crate::{LanguageMethods, Runner};
use anyhow::bail;
use serde::Deserialize;
use std::process::Command;
#[derive(Default, Deserialize)]
#[serde(deny_unknown_fields)]
struct LangConfig {
#[serde(default)]
path: String,
#[serde(default)]
pkg_config: Option<String>,
}
pub struct MoonBit;
impl LanguageMethods for MoonBit {
fn display(&self) -> &str {
"moonbit"
}
fn comment_prefix_for_test_config(&self) -> Option<&str> {
Some("//@")
}
fn default_bindgen_args(&self) -> &[&str] {
&["--derive-show", "--derive-eq", "--derive-error"]
}
fn prepare(&self, runner: &mut Runner) -> anyhow::Result<()> {
println!("Testing if MoonBit toolchain exists...");
if runner
.run_command(Command::new("moon").arg("version"))
.is_err()
{
bail!("MoonBit toolchain not found. Check out <https://www.moonbitlang.com/download>");
}
Ok(())
}
fn compile(&self, runner: &Runner, compile: &crate::Compile) -> anyhow::Result<()> {
let config = compile.component.deserialize_lang_config::<LangConfig>()?;
if !config.path.is_empty() {
let src_path = &compile.component.path;
let dest_path = compile.bindings_dir.join(&config.path);
std::fs::copy(src_path, dest_path)?;
if let Some(pkg_config) = config.pkg_config {
let dest_path = compile
.bindings_dir
.join(&config.path)
.parent()
.unwrap()
.join("moon.pkg.json");
std::fs::write(dest_path, pkg_config)?;
}
}
let manifest = compile.bindings_dir.join("moon.mod.json");
let mut cmd = Command::new("moon");
cmd.arg("build")
.arg("--no-strip") .arg("--manifest-path")
.arg(&manifest);
runner.run_command(&mut cmd)?;
let artifact = compile
.bindings_dir
.join("target/wasm/release/build/gen/gen.wasm");
let manifest_dir = compile.component.path.parent().unwrap();
let mut cmd = Command::new("wasm-tools");
cmd.arg("component")
.arg("embed")
.args(["--encoding", "utf16"])
.args(["-o", artifact.to_str().unwrap()])
.args(["-w", &compile.component.bindgen.world])
.arg(manifest_dir)
.arg(&artifact);
runner.run_command(&mut cmd)?;
let mut cmd = Command::new("wasm-tools");
cmd.arg("component")
.arg("new")
.args(["-o", compile.output.to_str().unwrap()])
.arg(&artifact);
runner.run_command(&mut cmd)?;
Ok(())
}
fn should_fail_verify(
&self,
name: &str,
config: &crate::config::WitConfig,
_args: &[String],
) -> bool {
config.async_ && name != "async-resource-func.wit"
}
fn verify(&self, runner: &Runner, verify: &crate::Verify) -> anyhow::Result<()> {
let manifest = verify.bindings_dir.join("moon.mod.json");
let mut cmd = Command::new("moon");
cmd.arg("check")
.arg("--warn-list")
.arg("-28")
.arg("--manifest-path")
.arg(&manifest);
runner.run_command(&mut cmd)?;
let mut cmd = Command::new("moon");
cmd.arg("build").arg("--manifest-path").arg(&manifest);
runner.run_command(&mut cmd)?;
Ok(())
}
}