revert converting to Config before merging

pull/9545/head
Dipsy 10 months ago
parent bcc5e38f59
commit eabee3745c

@ -10,14 +10,21 @@ use std::fs;
use std::io::Error as IOError; use std::io::Error as IOError;
use toml::de::Error as TomlError; use toml::de::Error as TomlError;
#[derive(Debug, Clone, PartialEq)] // Config loading error
pub struct Config { #[derive(Debug)]
pub workspace_config: bool, pub enum ConfigLoadError {
pub theme: Option<String>, BadConfig(TomlError),
pub keys: HashMap<Mode, KeyTrie>, Error(IOError),
pub editor: helix_view::editor::Config, }
impl Default for ConfigLoadError {
fn default() -> Self {
ConfigLoadError::Error(IOError::new(std::io::ErrorKind::NotFound, "place holder"))
}
} }
// Deserializable raw config struct
#[derive(Debug, Clone, PartialEq, Deserialize)] #[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(rename_all = "kebab-case", deny_unknown_fields)] #[serde(rename_all = "kebab-case", deny_unknown_fields)]
pub struct ConfigRaw { pub struct ConfigRaw {
@ -27,26 +34,60 @@ pub struct ConfigRaw {
pub editor: Option<toml::Value>, pub editor: Option<toml::Value>,
} }
impl Default for Config { impl Default for ConfigRaw {
fn default() -> Config { fn default() -> ConfigRaw {
Config { Self {
workspace_config: false, workspace_config: Some(false),
theme: None, theme: None,
keys: keymap::default(), keys: Some(keymap::default()),
editor: helix_view::editor::Config::default(), editor: None,
} }
} }
} }
#[derive(Debug)] impl ConfigRaw {
pub enum ConfigLoadError { fn load(file: PathBuf) -> Result<Self, ConfigLoadError> {
BadConfig(TomlError), let source = fs::read_to_string(file).map_err(ConfigLoadError::Error)?;
Error(IOError), toml::from_str(&source).map_err(ConfigLoadError::BadConfig)
}
fn merge(self, other: ConfigRaw, trust: bool) -> Self {
ConfigRaw {
workspace_config: match trust {
true => other.workspace_config.or(self.workspace_config),
false => self.workspace_config,
},
theme: other.theme.or(self.theme),
keys: match (self.keys, other.keys) {
(Some(a), Some(b)) => Some(merge_keys(a, b)),
(opt_a, opt_b) => opt_a.or(opt_b),
},
editor: match (self.editor, other.editor) {
(Some(a), Some(b)) => Some(merge_toml_values(a, b, 3)),
(opt_a, opt_b) => opt_a.or(opt_b),
}
}
}
} }
impl Default for ConfigLoadError { // Final config struct
fn default() -> Self { #[derive(Debug, Clone, PartialEq)]
ConfigLoadError::Error(IOError::new(std::io::ErrorKind::NotFound, "place holder")) pub struct Config {
pub workspace_config: bool,
pub theme: Option<String>,
pub keys: HashMap<Mode, KeyTrie>,
pub editor: helix_view::editor::Config,
}
impl Default for Config {
fn default() -> Config {
let raw = ConfigRaw::default();
Self {
workspace_config: raw.workspace_config.unwrap_or_default(),
theme: raw.theme,
keys: raw.keys.unwrap_or_else(|| keymap::default()),
editor: helix_view::editor::Config::default(),
}
} }
} }
@ -59,13 +100,6 @@ impl Display for ConfigLoadError {
} }
} }
impl ConfigRaw {
fn load(file: PathBuf) -> Result<Self, ConfigLoadError> {
let source = fs::read_to_string(file).map_err(ConfigLoadError::Error)?;
toml::from_str(&source).map_err(ConfigLoadError::BadConfig)
}
}
impl TryFrom<ConfigRaw> for Config { impl TryFrom<ConfigRaw> for Config {
type Error = ConfigLoadError; type Error = ConfigLoadError;
@ -73,10 +107,7 @@ impl TryFrom<ConfigRaw> for Config {
Ok(Self { Ok(Self {
workspace_config: config.workspace_config.unwrap_or_default(), workspace_config: config.workspace_config.unwrap_or_default(),
theme: config.theme, theme: config.theme,
keys: match config.keys { keys: config.keys.unwrap_or_else(|| keymap::default()),
Some(keys) => merge_keys(keymap::default(), keys),
None => keymap::default(),
},
editor: config.editor editor: config.editor
.map(|e| e.try_into()).transpose() .map(|e| e.try_into()).transpose()
.map_err(ConfigLoadError::BadConfig)? .map_err(ConfigLoadError::BadConfig)?
@ -87,32 +118,17 @@ impl TryFrom<ConfigRaw> for Config {
impl Config { impl Config {
pub fn load() -> Result<Config, ConfigLoadError> { pub fn load() -> Result<Config, ConfigLoadError> {
// Load and parse global config returning all errors let default = ConfigRaw::default();
let global: Config = ConfigRaw::load(helix_loader::config_file())?.try_into()?; let global = default.merge(ConfigRaw::load(helix_loader::config_file())?, true);
if global.workspace_config { match global.workspace_config.unwrap_or_default() {
global.merge(ConfigRaw::load(helix_loader::workspace_config_file())?) false => global,
} else { true => match ConfigRaw::load(helix_loader::workspace_config_file()) {
Ok(global) Ok(workspace) => Ok(global.merge(workspace, false)),
} Err(ConfigLoadError::Error(_)) => Ok(global),
} error => error,
}?,
fn merge(self, other: ConfigRaw) -> Result<Self, ConfigLoadError> { }.try_into()
Ok(Config {
workspace_config: other.workspace_config.unwrap_or(self.workspace_config),
theme: other.theme.or(self.theme),
keys: match other.keys {
Some(keys) => merge_keys(self.keys, keys),
None => self.keys,
},
editor: match other.editor {
None => self.editor,
Some(editor) => merge_toml_values(
toml::Value::try_from(self.editor).unwrap(),
editor, 3
).try_into().map_err(ConfigLoadError::BadConfig)?,
}
})
} }
} }
@ -123,7 +139,7 @@ mod tests {
impl Config { impl Config {
fn load_test(file: &str) -> Config { fn load_test(file: &str) -> Config {
let raw: ConfigRaw = toml::from_str(file).unwrap(); let raw: ConfigRaw = toml::from_str(file).unwrap();
raw.try_into().unwrap() ConfigRaw::default().merge(raw, true).try_into().unwrap()
} }
} }

Loading…
Cancel
Save