1#![allow(clippy::collapsible_if)]
2pub mod config;
3pub mod error;
4pub mod generics;
5pub mod index;
6pub mod merger;
7pub mod preprocessor;
8pub mod scanner;
9pub mod visitor;
10
11use config::Config;
12use error::Result;
13use std::path::PathBuf;
14
15#[derive(Default)]
17pub struct Generator {
18 inputs: Vec<PathBuf>,
19 includes: Vec<PathBuf>,
20 output_path: Option<PathBuf>,
21}
22
23impl Generator {
24 pub fn new() -> Self {
26 Self::default()
27 }
28
29 pub fn with_config(mut self, config: Config) -> Self {
31 if let Some(inputs) = config.input {
32 self.inputs.extend(inputs);
33 }
34 if let Some(includes) = config.include {
35 self.includes.extend(includes);
36 }
37 if let Some(output) = config.output {
38 self.output_path = Some(output);
39 }
40 self
41 }
42
43 pub fn input<P: Into<PathBuf>>(mut self, path: P) -> Self {
45 self.inputs.push(path.into());
46 self
47 }
48
49 pub fn include<P: Into<PathBuf>>(mut self, path: P) -> Self {
51 self.includes.push(path.into());
52 self
53 }
54
55 pub fn output<P: Into<PathBuf>>(mut self, path: P) -> Self {
57 self.output_path = Some(path.into());
58 self
59 }
60
61 pub fn generate(self) -> Result<()> {
63 let output = self.output_path.ok_or_else(|| {
64 std::io::Error::new(std::io::ErrorKind::InvalidInput, "Output path is required")
65 })?;
66
67 log::info!(
69 "Scanning directories: {:?} and includes: {:?}",
70 self.inputs,
71 self.includes
72 );
73 let snippets = scanner::scan_directories(&self.inputs, &self.includes)?;
74
75 log::info!("Merging {} snippets", snippets.len());
77 let merged_value = merger::merge_openapi(snippets)?;
78
79 if let Some(parent) = output.parent() {
82 std::fs::create_dir_all(parent)?;
83 }
84
85 let file = std::fs::File::create(&output)?;
86 let extension = output
87 .extension()
88 .and_then(|s| s.to_str())
89 .unwrap_or("yaml");
90
91 match extension {
92 "json" => {
93 serde_json::to_writer_pretty(file, &merged_value)?;
94 }
95 "yaml" | "yml" => {
96 serde_yaml::to_writer(file, &merged_value)?;
97 }
98 _ => {
99 serde_yaml::to_writer(file, &merged_value)?;
100 }
101 }
102
103 log::info!("Written output to {:?}", output);
104
105 Ok(())
106 }
107}