aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/input
diff options
context:
space:
mode:
authordenis <denismaximov98@gmail.com>2021-05-02 11:59:20 +0300
committerdenis <denismaximov98@gmail.com>2021-05-02 11:59:20 +0300
commit452940fb6530bc508d26c9ebaf6dd784751f6351 (patch)
treecd57bafebd00503eb6f12480a43d6aa9a02e45e5 /src/common/input
parentchore: clippy please allow it (diff)
parentdocs(changelog): Improved Config Loading #423 (diff)
downloadsl0ppij-452940fb6530bc508d26c9ebaf6dd784751f6351.tar.gz
sl0ppij-452940fb6530bc508d26c9ebaf6dd784751f6351.tar.xz
sl0ppij-452940fb6530bc508d26c9ebaf6dd784751f6351.zip
Merge branch 'main' into x-colors
Diffstat (limited to 'src/common/input')
-rw-r--r--src/common/input/config.rs135
1 files changed, 82 insertions, 53 deletions
diff --git a/src/common/input/config.rs b/src/common/input/config.rs
index 62ec3dfe..daa52b03 100644
--- a/src/common/input/config.rs
+++ b/src/common/input/config.rs
@@ -6,14 +6,17 @@ use std::io::{self, Read};
use std::path::{Path, PathBuf};
use super::keybinds::{Keybinds, KeybindsFromYaml};
-use crate::cli::ConfigCli;
+use crate::cli::{CliArgs, ConfigCli};
use crate::common::install;
use serde::Deserialize;
+use std::convert::TryFrom;
+
+const DEFAULT_CONFIG_FILE_NAME: &str = "config.yaml";
type ConfigResult = Result<Config, ConfigError>;
-/// Intermediate deserialisation config struct
+/// Intermediate deserialization config struct
#[derive(Debug, Deserialize)]
pub struct ConfigFromYaml {
pub keybinds: Option<KeybindsFromYaml>,
@@ -27,13 +30,13 @@ pub struct Config {
#[derive(Debug)]
pub enum ConfigError {
- // Deserialisation error
+ // Deserialization error
Serde(serde_yaml::Error),
// Io error
Io(io::Error),
// Io error with path context
IoPath(io::Error, PathBuf),
- // Internal Deserialisation Error
+ // Internal Deserialization Error
FromUtf8(std::string::FromUtf8Error),
}
@@ -44,6 +47,35 @@ impl Default for Config {
}
}
+impl TryFrom<&CliArgs> for Config {
+ type Error = ConfigError;
+
+ fn try_from(opts: &CliArgs) -> ConfigResult {
+ if let Some(ref path) = opts.config {
+ return Config::new(&path);
+ }
+
+ if let Some(ConfigCli::Config { clean, .. }) = opts.option {
+ if clean {
+ return Config::from_default_assets();
+ }
+ }
+
+ let config_dir = opts.config_dir.clone().or_else(install::default_config_dir);
+
+ if let Some(ref config) = config_dir {
+ let path = config.join(DEFAULT_CONFIG_FILE_NAME);
+ if path.exists() {
+ Config::new(&path)
+ } else {
+ Config::from_default_assets()
+ }
+ } else {
+ Config::from_default_assets()
+ }
+ }
+}
+
impl Config {
/// Uses defaults, but lets config override them.
pub fn from_yaml(yaml_config: &str) -> ConfigResult {
@@ -71,45 +103,6 @@ impl Config {
pub fn from_default_assets() -> ConfigResult {
Self::from_yaml(String::from_utf8(install::DEFAULT_CONFIG.to_vec())?.as_str())
}
-
- /// Entry point of the configuration
- #[cfg(not(test))]
- pub fn from_cli_config(
- location: Option<PathBuf>,
- cli_config: Option<ConfigCli>,
- config_dir: Option<PathBuf>,
- ) -> ConfigResult {
- if let Some(path) = location {
- return Config::new(&path);
- }
-
- if let Some(ConfigCli::Config { clean, .. }) = cli_config {
- if clean {
- return Config::from_default_assets();
- }
- }
-
- if let Some(config) = config_dir {
- let path = config.join("config.yaml");
- if path.exists() {
- Config::new(&path)
- } else {
- Config::from_default_assets()
- }
- } else {
- Config::from_default_assets()
- }
- }
-
- /// In order not to mess up tests from changing configurations
- #[cfg(test)]
- pub fn from_cli_config(
- _: Option<PathBuf>,
- _: Option<ConfigCli>,
- _: Option<PathBuf>,
- ) -> ConfigResult {
- Ok(Config::default())
- }
}
impl Display for ConfigError {
@@ -119,7 +112,7 @@ impl Display for ConfigError {
ConfigError::IoPath(ref err, ref path) => {
write!(formatter, "IoError: {}, File: {}", err, path.display(),)
}
- ConfigError::Serde(ref err) => write!(formatter, "Deserialisation error: {}", err),
+ ConfigError::Serde(ref err) => write!(formatter, "Deserialization error: {}", err),
ConfigError::FromUtf8(ref err) => write!(formatter, "FromUtf8Error: {}", err),
}
}
@@ -157,20 +150,56 @@ impl From<std::string::FromUtf8Error> for ConfigError {
// The unit test location.
#[cfg(test)]
mod config_test {
+ use std::io::Write;
+
+ use tempfile::tempdir;
+
use super::*;
#[test]
- fn clean_option_equals_default_config() {
- let cli_config = ConfigCli::Config { clean: true };
- let config = Config::from_cli_config(None, Some(cli_config), None).unwrap();
- let default = Config::default();
- assert_eq!(config, default);
+ fn try_from_cli_args_with_config() {
+ let arbitrary_config = PathBuf::from("nonexistent.yaml");
+ let mut opts = CliArgs::default();
+ opts.config = Some(arbitrary_config);
+ println!("OPTS= {:?}", opts);
+ let result = Config::try_from(&opts);
+ assert!(result.is_err());
+ }
+
+ #[test]
+ fn try_from_cli_args_with_option_clean() {
+ let mut opts = CliArgs::default();
+ opts.option = Some(ConfigCli::Config { clean: true });
+ let result = Config::try_from(&opts);
+ assert!(result.is_ok());
+ }
+
+ #[test]
+ fn try_from_cli_args_with_config_dir() {
+ let mut opts = CliArgs::default();
+ let tmp = tempdir().unwrap();
+ File::create(tmp.path().join(DEFAULT_CONFIG_FILE_NAME))
+ .unwrap()
+ .write_all(b"keybinds: invalid\n")
+ .unwrap();
+ opts.config_dir = Some(tmp.path().to_path_buf());
+ let result = Config::try_from(&opts);
+ assert!(result.is_err());
+ }
+
+ #[test]
+ fn try_from_cli_args_with_config_dir_without_config() {
+ let mut opts = CliArgs::default();
+ let tmp = tempdir().unwrap();
+ opts.config_dir = Some(tmp.path().to_path_buf());
+ let result = Config::try_from(&opts);
+ assert_eq!(result.unwrap(), Config::default());
}
#[test]
- fn no_config_option_file_equals_default_config() {
- let config = Config::from_cli_config(None, None, None).unwrap();
- let default = Config::default();
- assert_eq!(config, default);
+ fn try_from_cli_args_default() {
+ let opts = CliArgs::default();
+ let result = Config::try_from(&opts);
+ assert_eq!(result.unwrap(), Config::default());
}
}