1#![cfg(feature = "cli")]
3
4use crate::{Compiler, Config};
5use ccli::{clap, Parser};
6use std::{env, fs, path::PathBuf};
7
8#[derive(Debug, Parser)]
10#[command(name = "zinkc")]
11pub struct Compile {
12 #[clap(short, long)]
14 abi: bool,
15 #[clap(value_name = "INPUT")]
17 input: PathBuf,
18 #[clap(short, long)]
20 output: Option<PathBuf>,
21 #[clap(short, long)]
23 dispatcher: bool,
24}
25
26impl Compile {
27 pub fn run(&self) -> anyhow::Result<()> {
29 let output = if let Some(output) = self.output.as_ref() {
30 output.into()
31 } else {
32 env::current_dir()?.join(self.input.with_extension(""))
33 };
34
35 let compiler = Compiler::new(Config::default().dispatcher(self.dispatcher));
36 let artifact = compiler.compile(&fs::read(&self.input)?)?;
37
38 output.parent().map(fs::create_dir_all);
39 fs::write(&output, artifact.runtime_bytecode)?;
40
41 if !self.abi {
42 return Ok(());
43 }
44
45 let abi = output
46 .parent()
47 .ok_or_else(|| anyhow::anyhow!("invalid output path: {output:?}"))?
48 .join(
49 output
50 .file_name()
51 .ok_or_else(|| anyhow::anyhow!("invalid file name: {output:?}"))?,
52 )
53 .with_extension("abi.json");
54
55 fs::write(abi, serde_json::to_string_pretty(&artifact.abi)?)?;
56 Ok(())
57 }
58}