use std::fs::{File, OpenOptions};
use std::io::Write;
use std::path::PathBuf;
use std::sync::{Mutex, OnceLock};
use time::OffsetDateTime;
use time::format_description::well_known::Rfc3339;
static LOG_FILE: OnceLock<Mutex<File>> = OnceLock::new();
pub fn init() {
let Some(path) = default_path() else {
return;
};
if let Some(parent) = path.parent() {
let _ = std::fs::create_dir_all(parent);
}
let Ok(f) = OpenOptions::new().create(true).append(true).open(&path) else {
return;
};
let _ = LOG_FILE.set(Mutex::new(f));
}
pub fn default_path() -> Option<PathBuf> {
if let Some(p) = std::env::var_os("VORTO_LOG") {
return Some(PathBuf::from(p));
}
if let Some(xdg) = std::env::var_os("XDG_STATE_HOME") {
let mut p = PathBuf::from(xdg);
p.push("vorto");
p.push("vorto.log");
return Some(p);
}
let home = std::env::var_os("HOME")?;
let mut p = PathBuf::from(home);
p.push(".local");
p.push("state");
p.push("vorto");
p.push("vorto.log");
Some(p)
}
pub fn write(args: std::fmt::Arguments<'_>) {
let Some(lock) = LOG_FILE.get() else {
return;
};
let Ok(mut f) = lock.lock() else {
return;
};
let ts = OffsetDateTime::now_local()
.unwrap_or_else(|_| OffsetDateTime::now_utc())
.format(&Rfc3339)
.unwrap_or_else(|_| String::from("?"));
let _ = writeln!(f, "[{ts}] {args}");
}
#[macro_export]
macro_rules! vlog {
($($arg:tt)*) => {
$crate::log::write(::std::format_args!($($arg)*))
};
}