Skip to main content

oag_core/
lib.rs

1pub mod config;
2pub mod engine;
3pub mod error;
4pub mod ir;
5pub mod parse;
6pub mod transform;
7
8use thiserror::Error;
9
10/// A generated file with path and content.
11#[derive(Debug, Clone)]
12pub struct GeneratedFile {
13    pub path: String,
14    pub content: String,
15}
16
17/// Output from `engine::generate()`, separating source files (always overwritten)
18/// from scaffold files (write-once by default).
19#[derive(Debug, Clone)]
20pub struct GenerateOutput {
21    /// Source files derived from the OpenAPI spec — always overwritten on each run.
22    pub source_files: Vec<GeneratedFile>,
23    /// Project scaffold files (package.json, tsconfig, etc.) — only written if they
24    /// don't already exist on disk. Use `--force-scaffold` to override.
25    pub scaffold_files: Vec<GeneratedFile>,
26}
27
28/// Normalize whitespace in generated code:
29/// - Collapse 3+ consecutive newlines into 2 (max one blank line)
30/// - Ensure trailing newline
31pub fn normalize_generated(content: &str) -> String {
32    let mut result = String::with_capacity(content.len());
33    let mut newline_count = 0;
34    for ch in content.chars() {
35        if ch == '\n' {
36            newline_count += 1;
37            if newline_count <= 2 {
38                result.push(ch);
39            }
40        } else {
41            newline_count = 0;
42            result.push(ch);
43        }
44    }
45    if !result.ends_with('\n') {
46        result.push('\n');
47    }
48    result
49}
50
51/// Unified error type for code generators.
52#[derive(Debug, Error)]
53pub enum GeneratorError {
54    #[error("template render failed: {0}")]
55    Render(String),
56
57    #[error("generation failed: {0}")]
58    Other(String),
59}