use crate::modules::clock::ClockModule; use crate::modules::launcher::LauncherModule; use crate::modules::mpd::MpdModule; use crate::modules::script::ScriptModule; use crate::modules::sysinfo::SysInfoModule; use crate::modules::tray::TrayModule; use crate::modules::workspaces::WorkspacesModule; use dirs::config_dir; use serde::Deserialize; use std::fs; #[derive(Debug, Deserialize, Clone)] #[serde(tag = "type", rename_all = "kebab-case")] pub enum ModuleConfig { Clock(ClockModule), Mpd(MpdModule), Tray(TrayModule), Workspaces(WorkspacesModule), SysInfo(SysInfoModule), Launcher(LauncherModule), Script(ScriptModule), } #[derive(Debug, Deserialize, Clone, Default)] pub struct Config { pub left: Option>, pub center: Option>, pub right: Option>, pub monitors: Option>, } impl Config { pub fn load() -> Option { let config_dir = config_dir().expect("Failed to locate user config dir"); let extensions = vec!["json", "toml", "yaml", "yml", "corn"]; extensions.into_iter().find_map(|extension| { let full_path = config_dir .join("ironbar") .join(format!("config.{extension}")); if full_path.exists() { let file = fs::read(full_path).expect("Failed to read config file"); Some(match extension { "json" => serde_json::from_slice(&file).expect("Invalid JSON config"), "toml" => toml::from_slice(&file).expect("Invalid TOML config"), "yaml" | "yml" => serde_yaml::from_slice(&file).expect("Invalid YAML config"), "corn" => { // corn doesn't support deserialization yet // so serialize the interpreted result then deserialize that let file = String::from_utf8(file).expect("Config file contains invalid UTF-8"); let config = cornfig::parse(&file).expect("Invalid corn config").value; serde_json::from_str(&serde_json::to_string(&config).unwrap()).unwrap() } _ => unreachable!(), }) } else { None } }) } }