use std::{
fs,
io::Write,
env,
fmt::Display,
};
type DynRes<T> = Result<T, Box<dyn std::error::Error>>;
const XDG_ERR: &str =
"Error: debug_append, xdg_dir";
const EXISTS_ERR: &str =
"Error: debug_append, failed dir exists";
const DIR_CREATION_ERR: &str =
"Error: debug_append, failed dir creation";
const FOPEN_ERR: &str =
"Error: debug_append, failed file open";
const WRITE_ALL_ERR: &str =
"Error: debug_append, file write_all";
#[macro_export]
macro_rules! err {
($err:expr) => {
match $err {
Err(e) => return Err(Box::new(e)),
Ok(thing) => thing,
}
};
}
fn get_xdg_state_dir(
dir_name: impl Display,
) -> DynRes<String> {
const XDG_VAR: &str = "XDG_STATE_HOME";
const ALT_VAR: &str = "HOME";
const ALT_POSTFIX: &str = ".local/state";
let dir = if let Ok(dir) = env::var(XDG_VAR) {
dir
} else {
format!(
"{}/{ALT_POSTFIX}/{}",
env::var(ALT_VAR)?,
dir_name,
)
};
if !fs::exists(&dir)? {
fs::create_dir_all(&dir)?;
}
return Ok(dir);
}
#[cfg(debug_assertions)]
pub fn debug_append(
buf: impl AsRef<[u8]>,
fname: impl AsRef<str>,
dir_name: impl AsRef<str>,
) {
let dir = get_xdg_state_dir(dir_name.as_ref())
.expect(XDG_ERR);
if !fs::exists(&dir).expect(EXISTS_ERR) {
fs::create_dir_all(&dir).expect(DIR_CREATION_ERR);
}
let path = format!("{dir}/{}.log", fname.as_ref());
let mut file = fs::OpenOptions::new()
.read(true)
.append(true)
.create(true)
.open(path)
.expect(FOPEN_ERR);
let _ = &mut file.write_all(buf.as_ref())
.expect(WRITE_ALL_ERR);
}
pub fn append(
buf: impl AsRef<[u8]>,
fname: impl AsRef<str>,
dir_name: impl AsRef<str>,
) {
let dir = get_xdg_state_dir(dir_name.as_ref())
.expect(XDG_ERR);
if !fs::exists(&dir).expect(EXISTS_ERR) {
fs::create_dir_all(&dir).expect(DIR_CREATION_ERR);
}
let path = format!("{dir}/{}.log", fname.as_ref());
let mut file = fs::OpenOptions::new()
.read(true)
.append(true)
.create(true)
.open(path)
.expect(FOPEN_ERR);
let _ = &mut file.write_all(buf.as_ref())
.expect(WRITE_ALL_ERR);
}
#[cfg(debug_assertions)]
pub fn debug_err_append<'a, T, E: Display>(
error: &Result<T, E>,
fname: &str,
dir_name: &str,
) {
if let Err(err) = error {
let dir = get_xdg_state_dir(dir_name).expect(XDG_ERR);
let path = format!("{}/{}", dir, fname);
if !fs::exists(&path).expect(EXISTS_ERR)
{
fs::create_dir_all(&dir).expect(DIR_CREATION_ERR);
}
let mut file = fs::OpenOptions::new()
.read(true)
.append(true)
.create(true)
.open(path)
.expect(FOPEN_ERR);
let err_msg = err.to_string();
let _ = &mut file.write_all(
err_msg.as_ref()).expect(WRITE_ALL_ERR);
}
}
pub fn err_append<'a, T, E: Display>(
error: &Result<T, E>,
fname: &str,
dir_name: &str,
) {
if let Err(err) = error {
let dir = get_xdg_state_dir(dir_name).expect(XDG_ERR);
let path = format!("{}/{}", dir, fname);
if !fs::exists(&path).expect(EXISTS_ERR)
{
fs::create_dir_all(&dir).expect(DIR_CREATION_ERR);
}
let mut file = fs::OpenOptions::new()
.read(true)
.append(true)
.create(true)
.open(path)
.expect(FOPEN_ERR);
let err_msg = err.to_string();
let _ = &mut file.write_all(
err_msg.as_ref()).expect(WRITE_ALL_ERR);
}
}