1pub mod config;
2pub mod error;
3pub mod ir;
4pub mod parse;
5pub mod transform;
6
7use thiserror::Error;
8
9#[derive(Debug, Clone)]
11pub struct GeneratedFile {
12 pub path: String,
13 pub content: String,
14}
15
16pub fn normalize_generated(content: &str) -> String {
20 let mut result = String::with_capacity(content.len());
21 let mut newline_count = 0;
22 for ch in content.chars() {
23 if ch == '\n' {
24 newline_count += 1;
25 if newline_count <= 2 {
26 result.push(ch);
27 }
28 } else {
29 newline_count = 0;
30 result.push(ch);
31 }
32 }
33 if !result.ends_with('\n') {
34 result.push('\n');
35 }
36 result
37}
38
39#[derive(Debug, Error)]
41pub enum GeneratorError {
42 #[error("template render failed: {0}")]
43 Render(String),
44
45 #[error("generation failed: {0}")]
46 Other(String),
47}
48
49pub trait CodeGenerator {
51 fn id(&self) -> config::GeneratorId;
52 fn generate(
53 &self,
54 ir: &ir::IrSpec,
55 config: &config::GeneratorConfig,
56 ) -> Result<Vec<GeneratedFile>, GeneratorError>;
57}