openapi_nexus/config/
cli.rs1use std::collections::HashMap;
4use std::str::FromStr;
5
6use clap::Parser;
7
8use super::errors::ConfigError;
9use super::global_config::GlobalConfig;
10use crate::codegen::GeneratorType;
11
12#[derive(Debug, Parser)]
14#[command(name = "openapi-nexus")]
15#[command(about = "Generate code from OpenAPI 3.1 specifications")]
16#[command(version)]
17pub struct CliArgs {
18 #[command(subcommand)]
19 pub command: Commands,
20}
21
22#[derive(Debug, Parser)]
23pub enum Commands {
24 Generate {
26 #[arg(short, long, env = "OPENAPI_NEXUS_INPUT")]
28 input: String,
29
30 #[arg(short, long, env = "OPENAPI_NEXUS_VERBOSE")]
32 verbose: bool,
33
34 #[arg(long, env = "OPENAPI_NEXUS_CONFIG")]
36 config: Option<String>,
37
38 #[command(flatten)]
40 global: GlobalConfig,
41
42 #[arg(long = "generator-config", value_name = "GENERATOR.KEY=VALUE")]
48 generator_config: Vec<String>,
49 },
50}
51
52impl Commands {
53 pub fn parse_generator_overrides(
56 &self,
57 ) -> Result<HashMap<GeneratorType, toml::value::Table>, ConfigError> {
58 let generator_configs = match self {
59 Commands::Generate {
60 generator_config, ..
61 } => generator_config,
62 };
63
64 let mut overrides: HashMap<GeneratorType, toml::value::Table> = HashMap::new();
65
66 for config_str in generator_configs {
67 let parts: Vec<&str> = config_str.splitn(2, '=').collect();
69 if parts.len() != 2 {
70 return Err(ConfigError::ParseOverrides(format!(
71 "Invalid generator config format: '{}'. Expected format: <generator>.<key>=<value>",
72 config_str
73 )));
74 }
75
76 let key_part = parts[0];
77 let value_str = parts[1];
78
79 let key_parts: Vec<&str> = key_part.splitn(2, '.').collect();
81 if key_parts.len() != 2 {
82 return Err(ConfigError::ParseOverrides(format!(
83 "Invalid generator config format: '{}'. Expected format: <generator>.<key>=<value>",
84 config_str
85 )));
86 }
87
88 let generator_str = key_parts[0];
89 let key = key_parts[1].to_string();
90
91 let generator = GeneratorType::from_str(generator_str).map_err(|e| {
93 ConfigError::ParseOverrides(format!(
94 "Invalid generator name '{}': {}",
95 generator_str, e
96 ))
97 })?;
98
99 let toml_value = Self::parse_toml_value(value_str);
101
102 overrides
104 .entry(generator)
105 .or_default()
106 .insert(key, toml_value);
107 }
108
109 Ok(overrides)
110 }
111
112 fn parse_toml_value(value: &str) -> toml::Value {
114 if let Ok(b) = value.parse::<bool>() {
116 return toml::Value::Boolean(b);
117 }
118 if let Ok(i) = value.parse::<i64>() {
120 return toml::Value::Integer(i);
121 }
122 if let Ok(f) = value.parse::<f64>() {
124 return toml::Value::Float(f);
125 }
126 toml::Value::String(value.to_string())
128 }
129}