openapi_nexus_config/
config.rs1use std::collections::HashMap;
4
5use crate::cli::{CliArgs, Commands};
6use crate::config_file::ConfigFile;
7use crate::errors::ConfigError;
8use crate::global_config::GlobalConfig;
9use crate::loader::ConfigLoader;
10use openapi_nexus_common::GeneratorType;
11
12#[derive(Debug, Clone)]
14pub struct Config {
15 pub input: String,
17 pub global: GlobalConfig,
19 pub generators: HashMap<GeneratorType, toml::value::Table>,
21}
22
23impl Config {
24 pub fn load(cli_args: &CliArgs) -> Result<Self, ConfigError> {
33 let config_file = match &cli_args.command {
35 Commands::Generate {
36 config: Some(path), ..
37 } => Some(ConfigLoader::load_from_file(path)?),
38 Commands::Generate { .. } => ConfigLoader::discover_config_file()
39 .and_then(|path| ConfigLoader::load_from_file(&path).ok()),
40 };
41
42 Self::merge(config_file.as_ref(), cli_args)
44 }
45
46 fn merge(config_file: Option<&ConfigFile>, cli_args: &CliArgs) -> Result<Self, ConfigError> {
49 let mut config = Config {
50 input: String::new(),
51 global: GlobalConfig::default(),
52 generators: HashMap::new(),
53 };
54
55 if let Some(config_file) = config_file {
57 config.merge_file(config_file);
58 }
59
60 let (input, cli_global) = match &cli_args.command {
62 Commands::Generate { input, global, .. } => (input, global),
63 };
64 if input.is_empty() {
65 return Err(ConfigError::Validation(
66 "Input is required and cannot be empty".to_string(),
67 ));
68 }
69 let generator_overrides = cli_args.command.parse_generator_overrides()?;
70
71 config.input = input.clone();
72 config.merge_global(cli_global);
73 config.merge_generator_configs(&generator_overrides);
74 Ok(config)
75 }
76
77 fn merge_file(&mut self, config_file: &ConfigFile) {
78 self.merge_global(&config_file.global);
79 self.merge_generator_configs(&config_file.generators);
80 }
81
82 fn merge_global(&mut self, global: &GlobalConfig) {
83 if global.output.is_some() {
84 self.global.output = global.output.clone();
85 }
86 if global.generators.is_some() {
87 self.global.generators = global.generators.clone();
88 }
89 }
90
91 fn merge_generator_configs(
92 &mut self,
93 generator_configs: &HashMap<GeneratorType, toml::value::Table>,
94 ) {
95 for (generator, table_rhs) in generator_configs {
96 if let Some(table_lhs) = self.generators.get_mut(generator) {
97 for (key, value) in table_rhs.iter() {
98 table_lhs.insert(key.clone(), value.clone());
99 }
100 } else {
101 self.generators.insert(*generator, table_rhs.clone());
102 }
103 }
104 }
105}