diff options
Diffstat (limited to 'src/config_file.rs')
-rw-r--r-- | src/config_file.rs | 64 |
1 files changed, 34 insertions, 30 deletions
diff --git a/src/config_file.rs b/src/config_file.rs index 9d35873..dee21ed 100644 --- a/src/config_file.rs +++ b/src/config_file.rs @@ -17,9 +17,6 @@ use serde::Deserialize; use std::fs; use std::io; -const CONF_DIR: &str = "lsd"; -const CONF_FILE_NAME: &str = "config.yaml"; - /// A struct to hold an optional configuration items, and provides methods /// around error handling in a config file. #[derive(Eq, PartialEq, Debug, Deserialize)] @@ -144,27 +141,6 @@ impl Config { serde_yaml::from_str::<Self>(yaml) } - /// This provides the path for a configuration file, according to the XDG_BASE_DIRS specification. - /// return None if error like PermissionDenied - #[cfg(not(windows))] - pub fn config_file_path() -> Option<PathBuf> { - use xdg::BaseDirectories; - match BaseDirectories::with_prefix(CONF_DIR) { - Ok(p) => Some(p.get_config_home()), - Err(e) => { - print_error!("Can not open config file: {}.", e); - None - } - } - } - - /// This provides the path for a configuration file, inside the %APPDATA% directory. - /// return None if error like PermissionDenied - #[cfg(windows)] - pub fn config_file_path() -> Option<PathBuf> { - dirs::config_dir().map(|x| x.join(CONF_DIR)) - } - /// This expand the `~` in path to HOME dir /// returns the origin one if no `~` found; /// returns None if error happened when getting home dir @@ -189,16 +165,44 @@ impl Config { } }) } + + /// Config paths for non-Windows platforms will be read from + /// `$XDG_CONFIG_HOME/lsd` or `$HOME/.config/lsd` + /// (usually, those are the same) in that order. + /// The default paths for Windows will be read from + /// `%APPDATA%\lsd` or `%USERPROFILE%\.config\lsd` in that order. + /// This will apply both to the config file and the theme file. + pub fn config_paths() -> impl Iterator<Item = PathBuf> { + [ + dirs::config_dir(), + dirs::home_dir().map(|h| h.join(".config")), + ] + .iter() + .filter_map(|p| p.as_ref().map(|p| p.join("lsd"))) + .collect::<Vec<_>>() + .into_iter() + } } impl Default for Config { + /// Try to find either config.yaml or config.yml in the config directories + /// and use the first one that is found. If none are found, or the parsing fails, + /// use the default from DEFAULT_CONFIG. fn default() -> Self { - if let Some(p) = Self::config_file_path() { - if let Some(c) = Self::from_file(p.join(CONF_FILE_NAME)) { - return c; - } - } - Self::from_yaml(DEFAULT_CONFIG).unwrap() + Config::config_paths() + .find_map(|p| { + let yaml = p.join("config.yaml"); + let yml = p.join("config.yml"); + if yaml.is_file() { + Config::from_file(yaml) + } else if yml.is_file() { + Config::from_file(yml) + } else { + None + } + }) + .or(Self::from_yaml(DEFAULT_CONFIG).ok()) + .expect("Failed to read both config file and default config") } } |