From dbe6e6bc6c27b8763260b2a88a6c31c4424dbf45 Mon Sep 17 00:00:00 2001 From: thatpix3l Date: Fri, 28 Jan 2022 03:03:54 -0500 Subject: [PATCH] Load and save config to OS-specific config dirs --- src/settings.rs | 89 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 26 deletions(-) diff --git a/src/settings.rs b/src/settings.rs index 23a7deb..e0ac19d 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -4,9 +4,15 @@ use serde::{Deserialize, Serialize}; use tokio::{ fs::File, + fs::create_dir_all, io::{AsyncReadExt, AsyncWriteExt}, }; +use std::{ + env, + path::{Path,PathBuf}, +}; + // Structure for holding all the settings #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Settings { @@ -18,32 +24,63 @@ pub struct Settings { pub downloader: DownloaderConfig, } -impl Settings { - // Create new instance - pub fn new(username: &str, password: &str, client_id: &str, client_secret: &str) -> Settings { - Settings { - username: username.to_string(), - password: password.to_string(), - client_id: client_id.to_string(), - client_secret: client_secret.to_string(), - refresh_ui_seconds: 1, - downloader: DownloaderConfig::new(), - } - } +// On UNIX systems (eg. Linux, *BSD, even macOS), follow the +// XDG Base Directory Specification for storing config files +#[cfg(target_family = "unix")] +fn get_config_folder_path() -> PathBuf { + match env::var("XDG_CONFIG_HOME") { - // Serialize the settings to a json file - pub async fn save(&self) -> Result<(), SpotifyError> { - let data = serde_json::to_string_pretty(self)?; - let mut file = File::create("settings.json").await?; - file.write_all(data.as_bytes()).await?; - Ok(()) - } + Ok(v) => Path::new(&v).join("down_on_spot").to_path_buf(), - // Deserialize the settings from a json file - pub async fn load() -> Result { - let mut file = File::open("settings.json").await?; - let mut buf = String::new(); - file.read_to_string(&mut buf).await?; - Ok(serde_json::from_str(&buf)?) - } + Err(_) => Path::new(&env::var("HOME").unwrap()).join(".config/down_on_spot"), + + } +} + +// On Windows, follow whatever windows does for AppData +#[cfg(target_family = "windows")] +fn get_config_folder_path() -> PathBuf { + Path::new(&env::var("APPDATA").unwrap()).join("down_on_spot"); +} + +impl Settings { + // Create new instance + pub fn new(username: &str, password: &str, client_id: &str, client_secret: &str) -> Settings { + Settings { + username: username.to_string(), + password: password.to_string(), + client_id: client_id.to_string(), + client_secret: client_secret.to_string(), + refresh_ui_seconds: 1, + downloader: DownloaderConfig::new(), + } + } + + // Save config + pub async fn save(&self) -> Result<(), SpotifyError> { + // Get and create config folder path, generate config file path + let config_folder_path = get_config_folder_path(); + create_dir_all(&config_folder_path).await?; + let config_file_path = config_folder_path.join("settings.json"); + + + // Serialize the settings to a json file + let data = serde_json::to_string_pretty(self)?; + let mut file = File::create(config_file_path).await?; + file.write_all(data.as_bytes()).await?; + Ok(()) + } + + // Load config + pub async fn load() -> Result { + // Get config folder path, generate config file path + let config_folder_path = get_config_folder_path(); + let config_file_path = config_folder_path.join("settings.json"); + + // Deserialize the settings from a json file + let mut file = File::open(config_file_path).await?; + let mut buf = String::new(); + file.read_to_string(&mut buf).await?; + Ok(serde_json::from_str(&buf)?) + } }