use std::fmt;
use std::io::Write as _;
use std::path::Path;
use std::sync::{Mutex, OnceLock};
static TRANSCRIPT_FILE: OnceLock<Mutex<Option<std::fs::File>>> = OnceLock::new();
pub fn transcript_slot() -> &'static Mutex<Option<std::fs::File>> {
TRANSCRIPT_FILE.get_or_init(|| Mutex::new(None))
}
pub fn init_transcript(path: &Path) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
if let Some(parent) = path.parent()
&& !parent.as_os_str().is_empty()
{
std::fs::create_dir_all(parent)?;
}
let file = std::fs::File::create(path)?;
let mut guard = transcript_slot()
.lock()
.map_err(|_| "Transcript mutex poisoned")?;
*guard = Some(file);
Ok(())
}
pub fn println_tee(args: fmt::Arguments<'_>) {
let mut line = String::new();
let _ = fmt::write(&mut line, args);
{
let stdout = std::io::stdout();
let mut out = stdout.lock();
let _ = writeln!(out, "{line}");
}
if let Ok(mut guard) = transcript_slot().lock()
&& let Some(file) = guard.as_mut()
{
let _ = writeln!(file, "{line}");
let _ = file.flush();
}
}