1use crate::error::Result;
2use crate::generator::swagger_parser::fetch_and_parse_spec;
3use colored::*;
4use tabled::{Table, Tabled};
5
6#[derive(Tabled)]
7struct ModuleInfo {
8 #[tabled(rename = "Module")]
9 module: String,
10 #[tabled(rename = "Endpoints")]
11 endpoints: usize,
12 #[tabled(rename = "Schemas")]
13 schemas: usize,
14}
15
16pub async fn run(
17 spec: Option<String>,
18 all_specs: bool,
19 spec_name: Option<String>,
20 module: Option<String>,
21 schemas: bool,
22 _graph: bool,
23 json: bool,
24) -> Result<()> {
25 use crate::error::GenerationError;
26 use crate::specs::manager::{get_spec_by_name, list_specs};
27
28 let config = crate::config::loader::load_config()?;
30 crate::config::validator::validate_config(&config)?;
31
32 let specs = list_specs(&config);
34
35 if specs.is_empty() {
36 return Err(GenerationError::SpecPathRequired.into());
37 }
38
39 if specs.len() > 1 || all_specs {
41 if all_specs {
42 if json {
45 let mut all_specs_data = Vec::new();
47 for spec_entry in &specs {
48 let parsed =
49 crate::generator::swagger_parser::fetch_and_parse_spec(&spec_entry.path)
50 .await?;
51 all_specs_data.push(serde_json::json!({
52 "spec_name": spec_entry.name,
53 "spec_path": spec_entry.path,
54 "modules": parsed.modules.len(),
55 "total_endpoints": parsed.operations_by_tag.values().map(|v| v.len()).sum::<usize>(),
56 "total_schemas": parsed.schemas.len(),
57 "modules_detail": parsed.modules.iter().map(|m| {
58 let ops = parsed.operations_by_tag.get(m).map(|v| v.len()).unwrap_or(0);
59 let schemas_count = parsed.module_schemas.get(m).map(|v| v.len()).unwrap_or(0);
60 serde_json::json!({
61 "module": m,
62 "endpoints": ops,
63 "schemas": schemas_count
64 })
65 }).collect::<Vec<_>>()
66 }));
67 }
68 println!(
69 "{}",
70 serde_json::to_string_pretty(&serde_json::json!({
71 "specs": all_specs_data
72 }))
73 .map_err(|e| {
74 GenerationError::InvalidOperation {
75 message: format!("Failed to serialize JSON: {}", e),
76 }
77 })?
78 );
79 } else {
80 println!("{}", "🔍 Inspecting all OpenAPI specs...".bright_cyan());
82 println!();
83
84 for spec_entry in &specs {
85 println!("{}", format!("📋 Spec: {}", spec_entry.name).bright_green());
86 println!(" Path: {}", spec_entry.path);
87 let parsed =
88 crate::generator::swagger_parser::fetch_and_parse_spec(&spec_entry.path)
89 .await?;
90 println!(" • Total modules: {}", parsed.modules.len());
91 println!(
92 " • Total endpoints: {}",
93 parsed
94 .operations_by_tag
95 .values()
96 .map(|v| v.len())
97 .sum::<usize>()
98 );
99 println!(" • Total schemas: {}", parsed.schemas.len());
100 println!();
101 }
102 }
103 return Ok(());
104 } else if let Some(name) = spec_name {
105 let spec_entry = get_spec_by_name(&config, &name)?;
107 let spec_path = spec_entry.path;
108 let parsed = crate::generator::swagger_parser::fetch_and_parse_spec(&spec_path).await?;
109
110 if json {
111 let output = serde_json::json!({
112 "spec_name": name,
113 "spec_path": spec_path,
114 "modules": parsed.modules.len(),
115 "total_endpoints": parsed.operations_by_tag.values().map(|v| v.len()).sum::<usize>(),
116 "total_schemas": parsed.schemas.len(),
117 "modules_detail": parsed.modules.iter().map(|m| {
118 let ops = parsed.operations_by_tag.get(m).map(|v| v.len()).unwrap_or(0);
119 let schemas_count = parsed.module_schemas.get(m).map(|v| v.len()).unwrap_or(0);
120 serde_json::json!({
121 "module": m,
122 "endpoints": ops,
123 "schemas": schemas_count
124 })
125 }).collect::<Vec<_>>()
126 });
127 println!(
128 "{}",
129 serde_json::to_string_pretty(&output).map_err(|e| {
130 GenerationError::InvalidOperation {
131 message: format!("Failed to serialize JSON: {}", e),
132 }
133 })?
134 );
135 } else {
136 println!(
137 "{}",
138 format!("🔍 Inspecting OpenAPI spec: {}", name).bright_cyan()
139 );
140 println!(" Path: {}", spec_path);
141 println!();
142 println!("{}", "📊 Spec Summary:".bright_cyan());
143 println!(" • Total modules: {}", parsed.modules.len());
144 println!(
145 " • Total endpoints: {}",
146 parsed
147 .operations_by_tag
148 .values()
149 .map(|v| v.len())
150 .sum::<usize>()
151 );
152 println!(" • Total schemas: {}", parsed.schemas.len());
153 println!();
154
155 if let Some(module_name) = module {
156 if let Some(operations) = parsed.operations_by_tag.get(&module_name) {
158 println!("{}", format!("📦 Module: {}", module_name).bright_green());
159 println!(" • Endpoints: {}", operations.len());
160 if let Some(schema_names) = parsed.module_schemas.get(&module_name) {
161 println!(" • Schemas: {}", schema_names.len());
162 if schemas {
163 println!(" • Schema names:");
164 for schema in schema_names {
165 println!(" - {}", schema);
166 }
167 }
168 }
169 } else {
170 println!(
171 "{}",
172 format!("⚠️ Module '{}' not found", module_name).yellow()
173 );
174 }
175 } else {
176 let table_data: Vec<ModuleInfo> = parsed
178 .modules
179 .iter()
180 .map(|m| {
181 let endpoints = parsed
182 .operations_by_tag
183 .get(m)
184 .map(|v| v.len())
185 .unwrap_or(0);
186 let schemas_count =
187 parsed.module_schemas.get(m).map(|v| v.len()).unwrap_or(0);
188 ModuleInfo {
189 module: m.clone(),
190 endpoints,
191 schemas: schemas_count,
192 }
193 })
194 .collect();
195
196 let table = Table::new(table_data);
197 println!("{}", "📦 Modules:".bright_cyan());
198 println!("{}", table);
199 }
200 }
201 return Ok(());
202 } else {
203 let specs = list_specs(&config);
205 if specs.is_empty() {
206 return Err(GenerationError::SpecPathRequired.into());
207 }
208
209 println!("{}", "🔍 Inspecting all OpenAPI specs...".bright_cyan());
211 println!();
212
213 for spec_entry in &specs {
214 println!("{}", format!("📋 Spec: {}", spec_entry.name).bright_green());
215 println!(" Path: {}", spec_entry.path);
216 let parsed =
217 crate::generator::swagger_parser::fetch_and_parse_spec(&spec_entry.path)
218 .await?;
219 println!(" • Total modules: {}", parsed.modules.len());
220 println!(
221 " • Total endpoints: {}",
222 parsed
223 .operations_by_tag
224 .values()
225 .map(|v| v.len())
226 .sum::<usize>()
227 );
228 println!(" • Total schemas: {}", parsed.schemas.len());
229 println!();
230 }
231 return Ok(());
232 }
233 }
234
235 let spec_entry = if let Some(name) = spec_name {
237 get_spec_by_name(&config, &name)?
238 } else if let Some(cli_spec) = spec {
239 get_spec_by_name(&config, &cli_spec).unwrap_or_else(|_| {
241 specs
243 .iter()
244 .find(|s| s.path == cli_spec)
245 .cloned()
246 .ok_or(GenerationError::SpecPathRequired)
247 .unwrap()
248 })
249 } else {
250 specs[0].clone()
252 };
253
254 let spec_path = &spec_entry.path;
255 println!(
256 "{}",
257 format!("🔍 Inspecting OpenAPI spec: {}", spec_entry.name).bright_cyan()
258 );
259 println!();
260
261 let parsed = fetch_and_parse_spec(spec_path).await?;
262
263 if json {
264 let output = serde_json::json!({
266 "modules": parsed.modules.len(),
267 "total_endpoints": parsed.operations_by_tag.values().map(|v| v.len()).sum::<usize>(),
268 "total_schemas": parsed.schemas.len(),
269 "modules_detail": parsed.modules.iter().map(|m| {
270 let ops = parsed.operations_by_tag.get(m).map(|v| v.len()).unwrap_or(0);
271 let schemas_count = parsed.module_schemas.get(m).map(|v| v.len()).unwrap_or(0);
272 serde_json::json!({
273 "module": m,
274 "endpoints": ops,
275 "schemas": schemas_count
276 })
277 }).collect::<Vec<_>>()
278 });
279 println!(
280 "{}",
281 serde_json::to_string_pretty(&output).map_err(|e| {
282 crate::error::GenerationError::InvalidOperation {
283 message: format!("Failed to serialize JSON: {}", e),
284 }
285 })?
286 );
287 } else {
288 println!("{}", "📊 Spec Summary:".bright_cyan());
290 println!(" • Total modules: {}", parsed.modules.len());
291 println!(
292 " • Total endpoints: {}",
293 parsed
294 .operations_by_tag
295 .values()
296 .map(|v| v.len())
297 .sum::<usize>()
298 );
299 println!(" • Total schemas: {}", parsed.schemas.len());
300 println!();
301
302 if let Some(module_name) = module {
303 if let Some(operations) = parsed.operations_by_tag.get(&module_name) {
305 println!("{}", format!("📦 Module: {}", module_name).bright_green());
306 println!(" • Endpoints: {}", operations.len());
307 if let Some(schema_names) = parsed.module_schemas.get(&module_name) {
308 println!(" • Schemas: {}", schema_names.len());
309 if schemas {
310 println!(" • Schema names:");
311 for schema in schema_names {
312 println!(" - {}", schema);
313 }
314 }
315 }
316 } else {
317 println!(
318 "{}",
319 format!("⚠️ Module '{}' not found", module_name).yellow()
320 );
321 }
322 } else {
323 let table_data: Vec<ModuleInfo> = parsed
325 .modules
326 .iter()
327 .map(|m| {
328 let endpoints = parsed
329 .operations_by_tag
330 .get(m)
331 .map(|v| v.len())
332 .unwrap_or(0);
333 let schemas_count = parsed.module_schemas.get(m).map(|v| v.len()).unwrap_or(0);
334 ModuleInfo {
335 module: m.clone(),
336 endpoints,
337 schemas: schemas_count,
338 }
339 })
340 .collect();
341
342 let table = Table::new(table_data);
343 println!("{}", "📦 Modules:".bright_cyan());
344 println!("{}", table);
345 }
346 }
347
348 Ok(())
349}