use anyhow::Result; use serde_derive::{Deserialize, Serialize}; use structopt::StructOpt; use std::path::PathBuf; #[derive(Debug, Clone, StructOpt, Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] pub(crate) struct Config { pub(super) compile_commands_location: PathBuf, pub(super) extra_args: Vec, } #[derive(Debug, Clone, Default, StructOpt, Deserialize, Serialize)] #[serde(rename_all = "kebab-case")] pub(crate) struct ProvidedConfig { #[structopt(long = "clang-compile-commands-location")] pub(super) compile_commands_location: Option, #[structopt(long = "clang-extra-args", number_of_values = 1)] #[serde(default)] pub(super) extra_args: Vec, } impl Default for Config { fn default() -> Self { Config::from_merge( ProvidedConfig::default(), ProvidedConfig::default(), ) // Currently errors out only on CLI parse fail with clang's extra args .unwrap() } } impl Config { pub(crate) fn from_merge( cli: ProvidedConfig, mut config: ProvidedConfig, ) -> Result { let mut extra_args = Vec::new(); for args in cli.extra_args { extra_args.append(&mut ::shell_words::split(&args)?); } extra_args.append(&mut config.extra_args); Ok(Self { compile_commands_location: cli .compile_commands_location .or(config.compile_commands_location) .unwrap_or_else(|| PathBuf::from(r".")), extra_args, }) } }