From abbaaf66f2325641415487db1b4705e052300131 Mon Sep 17 00:00:00 2001 From: Rabindra Dhakal Date: Thu, 3 Oct 2024 08:27:38 +0545 Subject: [PATCH] feat(config): implement config loading --- src/core/config.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++ src/core/mod.rs | 1 + 2 files changed, 55 insertions(+) create mode 100644 src/core/config.rs diff --git a/src/core/config.rs b/src/core/config.rs new file mode 100644 index 0000000..c8f401c --- /dev/null +++ b/src/core/config.rs @@ -0,0 +1,54 @@ +use std::{env, fs, path::PathBuf, sync::LazyLock}; + +use serde::{Deserialize, Serialize}; + +/// Application's configuration +#[derive(Deserialize, Serialize)] +pub struct Config { + /// Path to the directory where app data is stored. + pub soar_path: String, +} + +impl Config { + /// Creates a new configuration by loading it from the configuration file. + /// If the configuration file is not found, it generates a new default configuration. + pub fn new() -> Self { + let home_config = env::var("XDG_CONFIG_HOME").unwrap_or_else(|_| { + env::var("HOME").map_or_else( + |_| panic!("Failed to retrieve HOME environment variable"), + |home| format!("{}/.config", home), + ) + }); + let pkg_config = PathBuf::from(home_config).join(env!("CARGO_PKG_NAME")); + let config_path = pkg_config.join("config.json"); + let content = match fs::read(&config_path) { + Ok(content) => content, + Err(e) if e.kind() == std::io::ErrorKind::NotFound => { + fs::create_dir_all(pkg_config).unwrap(); + Config::generate(config_path) + } + Err(e) => { + panic!("Error reading config file: {:?}", e); + } + }; + serde_json::from_slice(&content) + .unwrap_or_else(|e| panic!("Failed to parse config file: {:?}", e)) + } + + fn generate(config_path: PathBuf) -> Vec { + let def_config = Self { + soar_path: "$HOME/.soar".to_string(), + }; + let serialized = serde_json::to_vec_pretty(&def_config).unwrap(); + fs::write(config_path, &serialized).unwrap(); + serialized + } +} + +impl Default for Config { + fn default() -> Self { + Self::new() + } +} + +pub static CONFIG: LazyLock = LazyLock::new(Config::default); diff --git a/src/core/mod.rs b/src/core/mod.rs index e69de29..ef68c36 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -0,0 +1 @@ +pub mod config;