use crate::Router;
pub fn dump_if_requested(router: &Router) {
let val = match std::env::var("TAUT_DUMP_IR") {
Ok(v) if !v.is_empty() => v,
_ => return,
};
let ir = router.ir();
let json = match serde_json::to_string_pretty(&ir) {
Ok(s) => s,
Err(e) => {
eprintln!("taut-rpc: failed to serialize IR: {e}");
std::process::exit(2);
}
};
let target_is_stdout = matches!(val.as_str(), "1" | "true" | "stdout");
if target_is_stdout {
println!("{json}");
} else {
let path = std::path::PathBuf::from(&val);
if let Some(parent) = path.parent() {
if !parent.as_os_str().is_empty() {
if let Err(e) = std::fs::create_dir_all(parent) {
eprintln!("taut-rpc: failed to create {}: {e}", parent.display());
std::process::exit(2);
}
}
}
if let Err(e) = std::fs::write(&path, &json) {
eprintln!("taut-rpc: failed to write {}: {e}", path.display());
std::process::exit(2);
}
}
std::process::exit(0);
}
pub fn ir_json(router: &Router) -> Result<String, serde_json::Error> {
serde_json::to_string_pretty(&router.ir())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ir::Ir;
#[test]
fn ir_json_returns_parseable_ir_for_empty_router() {
let router = Router::new();
let json = ir_json(&router).expect("serialize empty IR");
let parsed: serde_json::Value =
serde_json::from_str(&json).expect("ir_json produced valid JSON");
assert!(parsed.is_object(), "IR root must be a JSON object");
let ir: Ir = serde_json::from_str(&json).expect("ir_json round-trips into Ir");
assert_eq!(ir.ir_version, Ir::CURRENT_VERSION);
assert!(ir.procedures.is_empty());
assert!(ir.types.is_empty());
}
#[test]
fn ir_json_is_pretty_printed() {
let router = Router::new();
let json = ir_json(&router).expect("serialize");
assert!(
json.contains('\n'),
"expected multi-line pretty JSON, got: {json}"
);
}
}