pub mod ats_gen;
pub mod compiler;
pub mod parser;
use anyhow::{Context, Result};
use std::fs;
use std::path::Path;
use crate::manifest::Manifest;
pub fn generate_all(manifest: &Manifest, output_dir: &str) -> Result<()> {
let out = Path::new(output_dir);
fs::create_dir_all(out).context("Failed to create output directory")?;
let mut all_signatures = Vec::new();
for source in &manifest.c_sources {
let source_path = Path::new(&source.path);
if source_path.exists() {
let sigs = parser::parse_c_header(&source.path)
.with_context(|| format!("Failed to parse C source: {}", source.path))?;
all_signatures.extend(sigs);
} else {
println!(
" [note] C source '{}' not found on disk; generating from ownership rules only",
source.path
);
}
}
let module = ats_gen::generate_module(
&manifest.project.name,
&all_signatures,
&manifest.ownership_rules,
&manifest.c_sources,
)?;
let sats_path = out.join(format!("{}_safe.sats", manifest.project.name));
let dats_path = out.join(format!("{}_safe.dats", manifest.project.name));
let (sats_content, dats_content) = ats_gen::render_module(&module)?;
fs::write(&sats_path, &sats_content)
.with_context(|| format!("Failed to write {}", sats_path.display()))?;
fs::write(&dats_path, &dats_content)
.with_context(|| format!("Failed to write {}", dats_path.display()))?;
println!(" [ok] Generated {}", sats_path.display());
println!(" [ok] Generated {}", dats_path.display());
Ok(())
}
pub fn build(manifest: &Manifest, release: bool) -> Result<()> {
println!("Building atsiser project: {}", manifest.project.name);
let output_dir = &manifest.project.output_dir;
let dats_file = format!("{}/{}_safe.dats", output_dir, manifest.project.name);
let cmd = compiler::build_command(manifest, &dats_file, release)?;
println!(" [cmd] {}", cmd.display());
if !Path::new(&dats_file).exists() {
anyhow::bail!(
"Generated file '{}' not found. Run 'atsiser generate' first.",
dats_file
);
}
compiler::execute_build(&cmd)?;
println!(" [ok] Build complete");
Ok(())
}
pub fn run(manifest: &Manifest, args: &[String]) -> Result<()> {
let binary = format!(
"{}/{}_safe",
manifest.project.output_dir,
manifest.project.name
);
println!("Running atsiser workload: {} {:?}", binary, args);
if !Path::new(&binary).exists() {
anyhow::bail!(
"Binary '{}' not found. Run 'atsiser build' first.",
binary
);
}
compiler::execute_run(&binary, args)?;
Ok(())
}