diff --git a/Cargo.lock b/Cargo.lock index a744e952..23fa66ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,7 +49,7 @@ dependencies = [ "arboard", "backtrace", "cgmath", - "directories-next", + "directories", "env_logger", "glium", "image", @@ -520,24 +520,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5" [[package]] -name = "directories-next" -version = "2.0.0" +name = "directories" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" dependencies = [ - "cfg-if", - "dirs-sys-next", + "dirs-sys", ] [[package]] -name = "dirs-sys-next" -version = "0.1.2" +name = "dirs-sys" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" dependencies = [ "libc", + "option-ext", "redox_users", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -1527,6 +1527,12 @@ dependencies = [ "pathdiff", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "orbclient" version = "0.3.46" diff --git a/Cargo.toml b/Cargo.toml index 7c282edf..cbd8b86e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,7 @@ winres = "0.1" arboard = "3.2" backtrace = "0.3" cgmath = "0.18" -directories-next = "2.0" +directories = "5.0" env_logger = "0.10" glium = "0.32" image = "0.24" diff --git a/src/configuration.rs b/src/configuration.rs index 7d278987..a5b8c055 100644 --- a/src/configuration.rs +++ b/src/configuration.rs @@ -1,15 +1,18 @@ -//! There are two files that store properties for Emulsion, the *cache* and the *config*. +//! There are two files that store properties for Alloy, the *cache* and the *config*. //! -//! The most important distinction between these is that Emulsion never writes to the *config* +//! The most important distinction between these is that Alloy never writes to the *config* //! but it does write to the *cache* to save portions of the state of the program (e.g. window size //! and position). //! //! Furthermore it's generally true that the user will only edit the *config* to specify their //! preferences. - -use std::{borrow::Cow, collections::BTreeMap, fs, path::Path}; - +//! +use directories::ProjectDirs; use serde::{Deserialize, Serialize}; +use std::{borrow::Cow, collections::BTreeMap, fs, path::Path, path::PathBuf}; + +/// Application name for project directories +const APPLICATION: &str = "Alloy"; #[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq, Eq)] #[serde(rename_all = "snake_case")] @@ -117,21 +120,21 @@ impl Cache { self.window.dark = theme == Theme::Dark; } - pub fn load>(file_path: P) -> Result { - let file_path = file_path.as_ref(); - let cfg_str = fs::read_to_string(file_path).map_err(|_| { - format!("Could not read cache from {:?}", file_path) + pub fn load() -> Result { + let file_path = cache_file(); + let cfg_str = fs::read_to_string(&file_path).map_err(|_| { + format!("Could not read cache from {file_path:?}") })?; let result: IncompleteCache = - toml::from_str(&cfg_str).map_err(|e| format!("{}", e))?; + toml::from_str(&cfg_str).map_err(|e| format!("{e}"))?; //println!("Read cache from file:\n{:#?}", result); Ok(result.into()) } - pub fn save>(&self, file_path: P) -> Result<(), String> { - let file_path = file_path.as_ref(); - let string = toml::to_string(self).map_err(|e| format!("{}", e))?; - fs::write(file_path, string).map_err(|_| { + pub fn save(&self) -> Result<(), String> { + let file_path = cache_file(); + let string = toml::to_string(self).map_err(|e| format!("{e}"))?; + fs::write(&file_path, string).map_err(|_| { format!("Could not write to cache file {:?}", file_path) })?; Ok(()) @@ -203,9 +206,9 @@ pub struct Configuration { } impl Configuration { - pub fn load>(file_path: P) -> Result { - let file_path = file_path.as_ref(); - let cfg_str = fs::read_to_string(file_path) + pub fn load() -> Result { + let file_path = config_file(); + let cfg_str = fs::read_to_string(&file_path) .map_err(|_| format!("Could not read config from {file_path:?}"))?; let result = toml::from_str(cfg_str.as_ref()).map_err(|e| format!("{e}"))?; @@ -213,3 +216,42 @@ impl Configuration { Ok(result) } } + +fn project_dir_fallback() -> PathBuf { + let exe_path = std::env::current_exe().unwrap(); + let exe_dir = exe_path.parent().unwrap(); + exe_dir.to_owned() +} + +fn config_file() -> PathBuf { + let config_dir = match ProjectDirs::from("", "", APPLICATION) { + Some(proj) => proj.config_dir().to_owned(), + None => project_dir_fallback(), + }; + if !config_dir.exists() { + std::fs::create_dir_all(&config_dir).unwrap(); + } + config_dir.join("cfg.toml") +} + +fn cache_file() -> PathBuf { + let cache_dir = match ProjectDirs::from("", "", APPLICATION) { + Some(proj) => proj.cache_dir().to_owned(), + None => project_dir_fallback(), + }; + if !cache_dir.exists() { + std::fs::create_dir_all(&cache_dir).unwrap(); + } + cache_dir.join("cache.toml") +} + +pub fn data_dir() -> PathBuf { + let data_dir = match ProjectDirs::from("", "", APPLICATION) { + Some(proj) => proj.data_local_dir().to_owned(), + None => project_dir_fallback(), + }; + if !data_dir.exists() { + std::fs::create_dir_all(&data_dir).unwrap(); + } + data_dir +} diff --git a/src/handle_panic.rs b/src/handle_panic.rs index 9a0689f8..93ae0d75 100644 --- a/src/handle_panic.rs +++ b/src/handle_panic.rs @@ -1,9 +1,7 @@ -use std::{env, fs::OpenOptions, io, io::Write, iter, panic, string::String}; +use std::{fs::OpenOptions, io, io::Write, iter, panic, string::String}; use backtrace::Backtrace; -use crate::PROJECT_DIRS; - pub fn handle_panic(info: &panic::PanicInfo) { let trace = Backtrace::new(); @@ -37,26 +35,11 @@ pub fn handle_panic(info: &panic::PanicInfo) { } fn write_to_file(msg: &str) -> io::Result<()> { - let local_data_folder = if let Some(ref project_dirs) = *PROJECT_DIRS { - project_dirs.data_local_dir().to_owned() - } else { - let curr_exe = env::current_exe()?; - let curr_exe_dir = curr_exe.parent().ok_or_else(|| { - io::Error::new( - io::ErrorKind::Other, - "Could not get exe parent folder!", - ) - })?; - curr_exe_dir.to_owned() - }; - if !local_data_folder.exists() { - std::fs::create_dir_all(&local_data_folder).unwrap(); - } + let data_dir = crate::configuration::data_dir(); let mut file = OpenOptions::new() .create(true) .append(true) - .open(local_data_folder.join("panic.txt"))?; - + .open(data_dir.join("panic.txt"))?; write!(file, "{msg}")?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index ede10262..ba3262a6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,13 +3,10 @@ use std::{ cell::{Cell, RefCell}, f32, - path::PathBuf, rc::Rc, sync::{Arc, Mutex}, }; -use directories_next::ProjectDirs; -use lazy_static::lazy_static; use log::trace; use crate::{ @@ -48,12 +45,6 @@ mod utils; mod version; mod widgets; -lazy_static! { - // The program name will be 'emulsion' - // (i.e. starting with a lower-case letter) on Linux - pub static ref PROJECT_DIRS: Option = ProjectDirs::from("", "", "Emulsion"); -} - static USAGE: &[u8] = include_bytes!("../resource/usage.png"); static LEFT_TO_PAN: &[u8] = include_bytes!("../resource/use-left-to-pan.png"); @@ -65,16 +56,12 @@ fn main() { env_logger::init(); trace!("Starting up. Panic hook set, logger initialized."); - // Load configuration and cache files - let (config_path, cache_path) = get_config_and_cache_paths(); - let args = cmd_line::parse_args(); - let cache = Cache::load(&cache_path); - let config = Configuration::load(config_path); - + let cache = Cache::load(); let first_launch = cache.is_err(); let cache = Arc::new(Mutex::new(cache.unwrap_or_default())); + let config = Configuration::load(); let config = Rc::new(RefCell::new(config.unwrap_or_default())); let mut application = Application::new(); @@ -270,7 +257,7 @@ fn main() { window.set_root(root_container); application.set_at_exit(Some(move || { - cache.lock().unwrap().save(cache_path).unwrap(); + cache.lock().unwrap().save().unwrap(); })); application.start_event_loop(); } @@ -356,29 +343,3 @@ fn make_picture_widget( }); picture_widget } - -pub fn get_config_and_cache_paths() -> (PathBuf, PathBuf) { - let config_folder; - let cache_folder; - - if let Some(ref project_dirs) = *PROJECT_DIRS { - config_folder = project_dirs.config_dir().to_owned(); - cache_folder = project_dirs.cache_dir().to_owned(); - } else { - let exe_path = std::env::current_exe().unwrap(); - let exe_folder = exe_path.parent().unwrap(); - config_folder = exe_folder.to_owned(); - cache_folder = exe_folder.to_owned(); - } - if !config_folder.exists() { - std::fs::create_dir_all(&config_folder).unwrap(); - } - if !cache_folder.exists() { - std::fs::create_dir_all(&cache_folder).unwrap(); - } - - ( - config_folder.join("cfg.toml"), - cache_folder.join("cache.toml"), - ) -}