use serde::Serialize;
use std::io::Write;
use std::sync::OnceLock;
pub const HOOK_LINE_PREFIX: &str = "__MACRA_HOOK__:";
#[derive(Serialize)]
pub struct ExpansionRecord {
pub name: String,
pub kind: String,
pub arguments: String,
pub input: String,
pub output: String,
}
static OUTPUT_FILE: OnceLock<Option<std::path::PathBuf>> = OnceLock::new();
fn output_file_path() -> &'static Option<std::path::PathBuf> {
OUTPUT_FILE.get_or_init(|| {
let dir = std::env::var_os("MACRA_HOOK_OUTPUT_DIR")?;
let path = std::path::PathBuf::from(dir).join(format!("{}.jsonl", std::process::id()));
Some(path)
})
}
pub fn log_expansion(record: &ExpansionRecord) {
let json = match serde_json::to_string(record) {
Ok(s) => s,
Err(_) => return,
};
if let Some(path) = output_file_path() {
if let Ok(mut f) = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(path)
{
let _ = writeln!(f, "{}", json);
return;
}
}
let _ = writeln!(std::io::stderr(), "{}{}", HOOK_LINE_PREFIX, json);
}