mod overlay; mod vk_layer; use std::{ fs::{self, File, OpenOptions}, io::Write, path::Path, }; use overlay::{Overlay, OverlayConfig}; static mut LOG_ENABLED: bool = true; static mut LOG_FILE: String = String::new(); static mut OVERLAY: Overlay = Overlay::new(); pub(crate) fn logging() -> bool { unsafe { LOG_ENABLED } } macro_rules! write_log { ($msg:expr) => { println!("{}", $msg); if crate::logging() { crate::log($msg); } }; } pub(crate) use write_log; fn get_config(home: &str) -> OverlayConfig { let config_path = Path::new(&home).join(".config/rFactorHUD/config.json"); if config_path.exists() { match fs::read_to_string(&config_path) { Ok(s) => serde_json::from_str(&s).unwrap_or_else(|err| { write_log!(format!( "failed to deserialize config file from {} \n({:?})", s, err )); OverlayConfig::new() }), Err(err) => { write_log!(format!( "failed to open config file: {:?} due to {:?}", config_path, err )); OverlayConfig::new() } } } else { write_log!("create parent dir structure"); if let Err(err) = std::fs::create_dir_all(config_path.parent().unwrap()) { write_log!(format!("failed to create dirs for config file: {:?}", err)); } let config = OverlayConfig::new(); match File::create(config_path) { Ok(mut file) => match serde_json::to_string_pretty(&config) { Ok(conf_str) => { write_log!("create config file with default values"); if let Err(err) = file.write_all(conf_str.as_bytes()) { write_log!(format!("failed to write to config file: {:?}", err)); } } Err(err) => { write_log!(format!("failed to serialize config: {:?}", err)); } }, Err(err) => { write_log!(format!("failed to create config file: {:?}", err)); } } config } } pub fn check_logging(home: &str) { let log_enabled = match std::env::var("RFACTOR_HUD_LOG") { Ok(var) => { let i: u32 = var.parse().unwrap_or(0); i == 1 } Err(_) => false, }; unsafe { LOG_ENABLED = log_enabled }; if logging() { unsafe { LOG_FILE = format!("{}/rf2_vk_hud.log", home); } if let Err(_) = File::create(unsafe { &LOG_FILE }) {} write_log!(" =================================================================="); write_log!(" ======================= New Negotiation =========================="); write_log!(" =================================================================="); } } pub fn log(msg: impl ToString) { assert!(logging()); if let Ok(mut file) = OpenOptions::new() .append(true) .create(true) .open(unsafe { &LOG_FILE }) { if let Err(_) = file.write_all(format!("{}\n", msg.to_string()).as_bytes()) {} } } #[cfg(test)] mod test { use crate::{check_logging, get_config}; #[test] fn config() { let home = std::env::var("HOME").unwrap(); check_logging(&home); let config = get_config(&home); println!("{:#?}", config); } }