diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index 4b71f5b7e..1d8383ff4 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -157,7 +157,7 @@ use crate::complete; use crate::config::config_from_environment; use crate::config::parse_config_args; use crate::config::CommandNameAndArgs; -use crate::config::ConfigArg; +use crate::config::ConfigArgKind; use crate::config::ConfigEnv; use crate::diff_util; use crate::diff_util::DiffFormat; @@ -3113,7 +3113,7 @@ pub struct EarlyArgs { } impl EarlyArgs { - fn merged_config_args(&self, matches: &ArgMatches) -> Vec { + fn merged_config_args(&self, matches: &ArgMatches) -> Vec<(ConfigArgKind, &str)> { merge_args_with( matches, &[ @@ -3121,8 +3121,8 @@ impl EarlyArgs { ("config_file", &self.config_file), ], |id, value| match id { - "config_toml" => ConfigArg::Toml(value.clone()), - "config_file" => ConfigArg::File(value.clone()), + "config_toml" => (ConfigArgKind::Toml, value.as_ref()), + "config_file" => (ConfigArgKind::File, value.as_ref()), _ => unreachable!("unexpected id {id:?}"), }, ) diff --git a/cli/src/config.rs b/cli/src/config.rs index b85d6f171..8e3fe5101 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -458,29 +458,40 @@ fn env_overrides_layer() -> ConfigLayer { layer } -/// Configuration source/data provided as command-line argument. -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ConfigArg { +/// Configuration source/data type provided as command-line argument. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum ConfigArgKind { /// `--config-toml=TOML` - Toml(String), + Toml, /// `--config-file=PATH` - File(String), + File, } /// Parses `--config-toml` arguments. -pub fn parse_config_args(toml_strs: &[ConfigArg]) -> Result, ConfigLoadError> { +pub fn parse_config_args( + toml_strs: &[(ConfigArgKind, &str)], +) -> Result, ConfigLoadError> { // It might look silly that a layer is constructed per argument, but // --config-toml argument can contain a full TOML document, and it makes // sense to preserve line numbers within the doc. If we add // --config=KEY=VALUE, multiple values might be loaded into one layer. let source = ConfigSource::CommandArg; - toml_strs - .iter() - .map(|arg| match arg { - ConfigArg::Toml(text) => ConfigLayer::parse(source, text), - ConfigArg::File(path) => ConfigLayer::load_from_file(source, path.into()), - }) - .try_collect() + let mut layers = Vec::new(); + for (kind, chunk) in &toml_strs.iter().chunk_by(|&(kind, _)| kind) { + match kind { + ConfigArgKind::Toml => { + for (_, text) in chunk { + layers.push(ConfigLayer::parse(source, text)?); + } + } + ConfigArgKind::File => { + for (_, path) in chunk { + layers.push(ConfigLayer::load_from_file(source, path.into())?); + } + } + } + } + Ok(layers) } /// Command name and arguments specified by config.