openapi_nexus_config/
merger.rs1use crate::cli::Commands;
4use crate::config::ConfigFile;
5use crate::global_config::GlobalConfig;
6use crate::typescript_config::TypeScriptConfig;
7use openapi_nexus_common::Language;
8
9pub struct ConfigMerger;
11
12impl ConfigMerger {
13 pub fn merge(
15 config_file: Option<&ConfigFile>,
16 cli_args: &crate::cli::CliArgs,
17 ) -> Result<ResolvedConfig, MergeError> {
18 let cli_global = match &cli_args.command {
20 Commands::Generate { global, .. } => global,
21 };
22
23 let cli_typescript = match &cli_args.command {
24 Commands::Generate { typescript, .. } => typescript,
25 };
26
27 let file_typescript = config_file.as_ref().map(|f| &f.typescript);
29
30 let merged_global = GlobalConfig {
34 input: cli_global.input.clone(),
35 output: cli_global.output.clone(),
36 language: cli_global.language,
37 };
38
39 let merged_typescript = TypeScriptConfig {
43 file_naming_convention: cli_typescript.file_naming_convention.clone(),
44 package_scope: cli_typescript
45 .package_scope
46 .clone()
47 .or_else(|| file_typescript.and_then(|c| c.package_scope.clone())),
48 package_name: cli_typescript
49 .package_name
50 .clone()
51 .or_else(|| file_typescript.and_then(|c| c.package_name.clone())),
52 generate_package: cli_typescript.generate_package,
53 ts_target: cli_typescript.ts_target.clone(),
54 ts_module: cli_typescript.ts_module.clone(),
55 ts_lib: cli_typescript
56 .ts_lib
57 .clone()
58 .or_else(|| file_typescript.and_then(|c| c.ts_lib.clone())),
59 generate_esm_config: cli_typescript.generate_esm_config,
60 include_build_scripts: cli_typescript.include_build_scripts,
61 };
62
63 let input = merged_global.input.clone();
65 let language = merged_global.language.unwrap_or(Language::TypeScript);
66 let resolved_global = merged_global.resolve(input, language).map_err(|msg| {
67 let err = MergeError::ValidationError(msg.clone());
68 tracing::error!("{}", err);
69 err
70 })?;
71
72 Ok(ResolvedConfig {
73 global: resolved_global,
74 typescript: merged_typescript,
75 })
76 }
77}
78
79#[derive(Debug, Clone)]
81pub struct ResolvedConfig {
82 pub global: GlobalConfig,
83 pub typescript: TypeScriptConfig,
84}
85
86#[derive(Debug)]
88pub enum MergeError {
89 ValidationError(String),
90}
91
92impl std::fmt::Display for MergeError {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 match self {
95 MergeError::ValidationError(msg) => {
96 write!(f, "Configuration validation error: {}", msg)
97 }
98 }
99 }
100}
101
102impl std::error::Error for MergeError {}