use std::fmt::{Debug, Display};
use crate::printer::pretty_ast::ToDocument;
pub struct DebugJSON<T: serde::Serialize>(pub T);
impl<T: serde::Serialize> Display for DebugJSON<T> {
#[cfg(not(unix))]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "<unknown, DebugJSON supported on unix plateforms only>")
}
#[cfg(unix)]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
const PATH: &str = "/tmp/hax-ast-debug.json";
fn append_line_json(value: &serde_json::Value) -> std::io::Result<usize> {
use std::io::{BufRead, BufReader, Write};
cleanup();
let file = std::fs::OpenOptions::new()
.read(true)
.append(true)
.create(true)
.open(PATH)?;
let count = BufReader::new(&file).lines().count();
writeln!(&file, "{value}")?;
Ok(count)
}
fn cleanup() {
static DID_RUN: AtomicBool = AtomicBool::new(false);
use std::sync::atomic::{AtomicBool, Ordering};
if DID_RUN
.compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire)
.is_ok()
{
let _ignored = std::fs::remove_file(PATH);
}
}
if let Ok(id) = append_line_json(&serde_json::to_value(&self.0).unwrap()) {
write!(f, "`just debug-json {id}`")
} else {
write!(f, "<DebugJSON failed>")
}
}
}
impl<A: 'static + Clone, P, T: serde::Serialize + Debug> ToDocument<P, A> for DebugJSON<T> {
fn to_document(&self, _: &P) -> super::DocBuilder<A> {
pretty::DocAllocator::as_string(
&pretty::BoxAllocator,
serde_json::to_string_pretty(&self.0).unwrap_or_else(|_| format!("{:#?}", &self.0)),
)
}
}